Skip to main content

Python bindings for AWS Systems Manager Session Manager protocol

Project description

aws-ssm-bridge

A Rust library implementing the AWS Systems Manager (SSM) Session Manager protocol with Python bindings.

License Rust Python unsafe


⚠️ Disclaimer

This project is not affiliated with, endorsed by, or sponsored by Amazon Web Services, Inc. or any of its affiliates.

This is an independent implementation of the SSM Session Manager protocol.


Overview

Unlike the official AWS Session Manager Plugin (a CLI binary written in Go), aws-ssm-bridge is a library designed for embedding in your applications.

Features

  • Binary Protocol: Full 116-byte AWS header, SHA-256 digest validation
  • Reliable Delivery: Sequence tracking, ACK/retransmission, RTT estimation (Jacobson/Karels)
  • Lock-Free Architecture: Dedicated writer task via mpsc channel, no mutex contention
  • Dead Connection Detection: Pong-based heartbeat tracking with configurable threshold
  • Interactive Shell: Raw terminal mode, resize handling (SIGWINCH)
  • Port Forwarding: TCP tunneling via PortForwarder
  • Python Bindings: Async support via PyO3, type stubs included
  • Security: #![forbid(unsafe_code)], zeroize token scrubbing, rate limiting, SSRF protection, target validation

Installation

Rust

[dependencies]
aws-ssm-bridge = "0.3"
tokio = { version = "1", features = ["full"] }

Python

pip install aws-ssm-bridge

Quick Start

Interactive Shell

use aws_ssm_bridge::interactive::{InteractiveShell, InteractiveConfig};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let config = InteractiveConfig::default();
    let mut shell = InteractiveShell::new(config)?;
    
    // Connect and run interactive session
    // Handles raw mode, resize (SIGWINCH), signals (Ctrl+C/D/Z)
    shell.connect("i-0123456789abcdef0").await?;
    shell.run().await?;
    Ok(())
}

Programmatic Session

use aws_ssm_bridge::{SessionManager, SessionConfig};
use futures::StreamExt;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let manager = SessionManager::new().await?;
    
    let mut session = manager.start_session(SessionConfig {
        target: "i-0123456789abcdef0".into(),
        ..Default::default()
    }).await?;
    
    let mut output = session.output();
    tokio::spawn(async move {
        while let Some(data) = output.next().await {
            print!("{}", String::from_utf8_lossy(&data));
        }
    });
    
    session.send(b"hostname\n").await?;
    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
    session.terminate().await?;
    
    Ok(())
}

Port Forwarding

use aws_ssm_bridge::{SessionManager, PortForwardConfig, PortForwarder};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let manager = SessionManager::new().await?;
    
    let forwarder = PortForwarder::new(&manager, PortForwardConfig {
        target: "i-0123456789abcdef0".into(),
        local_port: 8080,
        remote_port: 80,
        ..Default::default()
    }).await?;
    
    println!("Forwarding localhost:8080 -> remote:80");
    forwarder.wait().await?;
    Ok(())
}

Python

import asyncio
from aws_ssm_bridge import SessionManager

async def main():
    manager = await SessionManager.new()
    
    async with await manager.start_session(target="i-0123456789abcdef0") as session:
        await session.send(b"hostname\n")
        async for chunk in await session.output():
            print(chunk.decode(), end="")

asyncio.run(main())

Type-Safe Documents

Use type-safe document wrappers instead of magic strings:

use aws_ssm_bridge::{SessionBuilder, documents::*};

// Port forwarding to instance
let session = SessionBuilder::new("i-xxx")
    .document(PortForwardingSession::builder()
        .remote_port(3306)
        .local_port(13306)
        .build())
    .build().await?;

// Port forwarding through bastion to RDS
let session = SessionBuilder::new("i-bastion")
    .document(PortForwardingToRemoteHost::new("mydb.rds.amazonaws.com", 3306))
    .build().await?;

// SSH over Session Manager
let session = SessionBuilder::new("i-xxx")
    .document(SshSession::new())
    .build().await?;

// Interactive command execution
let session = SessionBuilder::new("i-xxx")
    .document(InteractiveCommand::new("top"))
    .build().await?;

Documentation


Examples

Rust Examples (examples/)

Example Description
interactive_shell.rs Full interactive shell with raw mode, resize, signals
shell_session.rs Programmatic shell session (send commands, read output)
port_forwarding.rs TCP port forwarding through SSM
session_pool.rs Managing multiple concurrent sessions
reconnecting.rs Auto-reconnection with exponential backoff
metrics_session.rs Session with observability hooks

Run with: cargo run --example interactive_shell -- i-0123456789abcdef0

Python Examples (python_examples/)

Example Description
interactive_shell.py Full interactive shell with raw terminal mode
shell_session.py Basic shell session with context manager
port_forwarding.py TCP port forwarding
multiple_sessions.py Concurrent sessions to multiple instances

Run with: python python_examples/interactive_shell.py i-0123456789abcdef0


Architecture

src/
├── lib.rs              # Public API
├── binary_protocol.rs  # 116-byte header, SHA-256
├── session.rs          # Session lifecycle, target validation
├── connection.rs       # WebSocket, writer task, retransmit, pong tracking
├── channels.rs         # BroadcastStream-backed output multiplexer
├── ack.rs              # ACK tracking, RTT (Jacobson/Karels)
├── handshake.rs        # 3-phase handshake
├── port_forward.rs     # TCP tunneling
├── rate_limit.rs       # Token bucket
└── python/             # PyO3 bindings

Security

  • #![forbid(unsafe_code)]
  • zeroize scrubs session tokens from memory on drop
  • Target format validation (EC2 instance, managed instance, ARN)
  • SSRF protection (AWS endpoint validation)
  • Rate limiting (configurable token bucket)
  • TLS required (WSS only)
  • Dead connection detection via pong tracking
  • AWS transport encryption (all SSM traffic is encrypted)

See Security Documentation for threat model and details.


License

MIT License. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aws_ssm_bridge-0.3.0.tar.gz (830.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

aws_ssm_bridge-0.3.0-cp38-abi3-win_amd64.whl (5.8 MB view details)

Uploaded CPython 3.8+Windows x86-64

aws_ssm_bridge-0.3.0-cp38-abi3-manylinux_2_39_x86_64.whl (8.4 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.39+ x86-64

aws_ssm_bridge-0.3.0-cp38-abi3-macosx_11_0_arm64.whl (5.6 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

Details for the file aws_ssm_bridge-0.3.0.tar.gz.

File metadata

  • Download URL: aws_ssm_bridge-0.3.0.tar.gz
  • Upload date:
  • Size: 830.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aws_ssm_bridge-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4d5e75a2885295fb5eb4d60988af9ffa2beb51d213894f4af74bb5f07f417a7b
MD5 5b8b6b812aa01d8dc87f3eb514d5d92c
BLAKE2b-256 0e068a13750d575442561dae20c10fae210b1730ecb1cda6abc0bd8c940197ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for aws_ssm_bridge-0.3.0.tar.gz:

Publisher: release.yml on hupe1980/aws-ssm-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aws_ssm_bridge-0.3.0-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for aws_ssm_bridge-0.3.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 bef5ae394fcd71b1f7c40593173cb43a6aa2c4e5cede3e2878a4b03c4ab701eb
MD5 7bb973daaf1b460130629aeb05f2eb96
BLAKE2b-256 a7a5e22d79ab5cddb24a07ded0d25138f502d1cbbcfdcf168929d5dbe3ed06d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for aws_ssm_bridge-0.3.0-cp38-abi3-win_amd64.whl:

Publisher: release.yml on hupe1980/aws-ssm-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aws_ssm_bridge-0.3.0-cp38-abi3-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for aws_ssm_bridge-0.3.0-cp38-abi3-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 e4a68a7fc8a7e4c3c2548df7ebe85a43c2366f6b17a39125acf5989caa3791ba
MD5 d72e767a7b543336e5e7f87469429732
BLAKE2b-256 54e3b0adecfe920540e2fb76c9510dc848d6e2a35af84b5e46158a99ae31766d

See more details on using hashes here.

Provenance

The following attestation bundles were made for aws_ssm_bridge-0.3.0-cp38-abi3-manylinux_2_39_x86_64.whl:

Publisher: release.yml on hupe1980/aws-ssm-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aws_ssm_bridge-0.3.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for aws_ssm_bridge-0.3.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a2d5c879cc498e320cc8c2113bb64b8e3ce62d7c6a9bc7a2f412e1996a5f5c0c
MD5 45355b2d8dcee38d67a5b6db134c69b9
BLAKE2b-256 81caf3a6d427e65f8a3376784eef6e8818b4a28a34bc97118f9543ddf91d4007

See more details on using hashes here.

Provenance

The following attestation bundles were made for aws_ssm_bridge-0.3.0-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on hupe1980/aws-ssm-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page