EC2 SSH Access (SSM)
Overview
This pattern grants SSH access to EC2 Linux instances without opening inbound SSH or running a bastion. At checkout the broker generates an ephemeral SSH key pair locally and uses an AWS Systems Manager (SSM) document (addSSHKey) to push the public key onto the target instance; it returns the private key. At checkin a second document (removeSSHKey) removes the key. Because SSM drives the change, the broker only needs AWS API access — not network reachability to the instance.
Before You Begin
- The Access Broker is deployed and connected
- AWS CLI on the broker host, with permission to call
ssm send-commandandssm list-command-invocations - The target EC2 instances have the SSM Agent running and an instance profile that allows SSM
- The
addSSHKeyandremoveSSHKeySSM documents registered in the account/region
How It Works
checkout → ssh-keygen (ephemeral) → ssm send-command addSSHKey
→ poll until Success → return private key
checkin → ssm send-command removeSSHKeyEnvironment Variables
| Variable | Notes |
|---|---|
BRITIVE_ACTION | Injected — checkout or checkin |
BRITIVE_USER_EMAIL | Injected — username derived from local-part (non-alphanumerics stripped) |
INSTANCE | Target EC2 instance ID |
BRITIVE_SUDO | 1 to grant sudo, 0 otherwise (default 0) |
Script
Full script: EC2/Linux/addLocalUser/ec2-ssh-user.sh
if [ "$ACTION" = "checkout" ]; then
KEY_PATH="$(mktemp -d)/britive-id_rsa"
ssh-keygen -q -N "" -t rsa -f "$KEY_PATH"
COMMAND_ID=$(aws ssm send-command \
--document-name "addSSHKey" \
--targets "Key=InstanceIds,Values=$INSTANCE" \
--parameters "username=[\"$USER\"],group=[\"$GROUP\"],sshPublicKey=[\"$(cat $KEY_PATH.pub)\"],sudo=[\"$SUDO\"],userEmail=[\"$USER_EMAIL\"]" \
--region "us-west-2" --query "Command.CommandId" --output text)
# poll list-command-invocations until Status = Success, then:
cat "$KEY_PATH" # return the private key
else
aws ssm send-command --document-name "removeSSHKey" \
--targets "Key=InstanceIds,Values=$INSTANCE" \
--parameters "username=[\"$USER\"]" --region "us-west-2"
fiThe example hardcodes us-west-2. Parameterize the region (e.g. an AWS_REGION variable) for multi-region fleets.
Configure in Britive
Create the permission
Resource Manager → Resource Type Permissions → New Permission. Language = Shell. Paste the script into both Checkout and Checkin — it branches on BRITIVE_ACTION. Declare INSTANCE and BRITIVE_SUDO; BRITIVE_ACTION and BRITIVE_USER_EMAIL are system-defined. Attach a response template that surfaces the private key.
Create a profile and policy
Create a profile (e.g. 2h), associate the instances (by resource label), add the permission, and add a policy assigning members by tag.
Verify
Check out and connect
Check out the profile, save the returned private key, then:
ssh -i britive-id_rsa <username>@<instance-private-ip>Check in and confirm removal
After checkin, the key is removed — a new SSH attempt with it is rejected.
Troubleshoot
| Symptom | Cause | Fix |
|---|---|---|
send-command returns empty | Instance not SSM-managed | Confirm the SSM Agent is running and the instance profile allows SSM |
| Command stuck pending | SSM document missing | Register the addSSHKey / removeSSHKey documents in the region |
AccessDenied | Broker IAM can’t call SSM | Grant ssm:SendCommand and ssm:ListCommandInvocations |
| Wrong region | Hardcoded us-west-2 | Parameterize the region for the instance’s region |