Back to resources

Zero Standing Privileges in Action: How Britive and AWS SSM Secure EC2 Access

June 2025  /  6 min. read   /  
Palak Chheda

ZSP in Action: How Britive and AWS SSM Secure EC2 Access

Britive has proven to be a powerful privilege management platform for all our customers. Allowing customers to manage zero standing privileges across cloud and on-premises infrastructure. 

As our customers begin to use Britive across their hybrid and multi-cloud environments, they have been able to leverage the flexibility afforded by Britive’s Access Broker to unlock new access patterns while reducing pain or, in some cases, improving user experience. 

This blog will discuss one such case where technology components provided by both Britive and AWS worked together to help one of our customers. 

Amazon EC2 (Elastic Compute Cloud) instances are virtual servers in AWS that provide scalable computing capacity, allowing users to run applications in the cloud. AWS Systems Manager (SSM) is a powerful service that enables secure management of EC2 instances and other AWS resources at scale, without needing direct SSH or RDP access. 

Through SSM, administrators can use SSM Documents — JSON or YAML templates that define actions for tasks such as running shell commands, automating software installation, or managing user access. By associating these documents with EC2 instances, users can execute predefined or custom commands across multiple instances securely and consistently. The power of these documents allowed us to unlock zero-standing privileges for users across all EC2 flavors. 

Brtitive’s Access Broker is a flexible, lightweight access orchestrator that allows our customers to bring a singular control plane and access policy enforcements leveraged for cloud entitlements to platforms and services that are not managed by cloud permissions. The broker in this scenario invokes the right SSM document to grant short-lived privileges for a domain or a local user to EC2 instances (servers) running across multi-account AWS infrastructure. 

AWS SSM Agent Capabilities

SSM Agent Capabilities

SSM provides some key benefits, including but not limited to:

  • Full audit logging to CloudTrail or S3
  • Send agent logs to CloudWatch for monitoring and alerting
  • Track command output, session activity, and automation results
  • Automatically enforce settings, scripts, domain join, or install agents on startup
  • Secure File Transfer

SSM Documents, such as the following, can be set up to grant short-lived local group memberships to domain users on the Windows machine that is joined to the same domain. Alternatively, a temporary local user account can be created for a specific user. These documents are invoked by the broker running on a central AWS account or individually on each Account. Cross-account access, when provided to the container or instances running the broker, can allow a smaller broker footprint while enabling powerful access control.

  1. Add an AD User to a local admin group.
{
    "schemaVersion": "2.2",
    "description": "Add AD user to local Administrators group for JIT access.",
    "parameters": {
      "username": {
        "type": "String",
        "description": "Active Directory username (e.g., DOMAIN\\jdoe)"
      }
    },
    "mainSteps": [
      {
        "action": "aws:runPowerShellScript",
        "name": "addADUserToAdmins",
        "inputs": {
          "runCommand": [
            "$username = \"{{ username }}\"",
            "Write-Output \"DEBUG: Username = [$username]\"",
            "if ([string]::IsNullOrWhiteSpace($username)) { Write-Error 'Username must be provided'; exit 1 }",
            "Add-LocalGroupMember -Group 'Administrators' -Member $username"
          ]
        }
      }
    ]
  }
  
  1. Remove the user from the local admin group.
{
  "schemaVersion": "2.2",
  "description": "Remove AD user from local Administrators group and log them out.",
  "parameters": {
    "username": {
      "type": "String",
      "description": "Active Directory username (e.g., DOMAIN\\jdoe)"
    }
  },
  "mainSteps": [
    {
      "action": "aws:runPowerShellScript",
      "name": "removeADUser",
      "inputs": {
        "runCommand": [
          "$username = \"{{username}}\"",
          "Write-Output \"DEBUG: Username = $username\"",
          "if (-not $username) { Write-Error 'Username must be provided'; exit 1 }",
          "Try {",
          "  $groupMembers = Get-LocalGroupMember -Group 'Administrators' | ForEach-Object { $_.Name }",
          "  if ($groupMembers -contains $username) {",
          "    Remove-LocalGroupMember -Group 'Administrators' -Member $username",
          "    Write-Output \"User $username removed from Administrators group.\"",
          "  } else {",
          "    Write-Output \"User $username is not a member of Administrators group. Skipping removal.\"",
          "  }",
          "} Catch {",
          "  Write-Error $_.Exception.Message",
          "  exit 1",
          "}"
        ]
      }
    },
    {
      "action": "aws:runPowerShellScript",
      "name": "logOffUser",
      "inputs": {
        "runCommand": [
          "$username = \"{{username}}\"",
          "Write-Output \"DEBUG: Username for logoff = $username\"",
          "$quserOutput = quser 2>&1",
          "if ($quserOutput -is [string]) { $quserOutput = $quserOutput -split \"`n\" }",
          "$matchingSessions = @()",
          "foreach ($line in $quserOutput) {",
          "  if ($line -match \"(?i)^\\s*(.*?)\\s+(\\w+)\\s+(\\d+)\") {",
          "    $user = $matches[1].Trim()",
          "    $sessionId = $matches[3]",
          "    if ($user -ieq $username) {",
          "      $matchingSessions += $sessionId",
          "    }",
          "  }",
          "}",
          "if ($matchingSessions.Count -eq 0) {",
          "  Write-Output \"No active sessions found for user $username.\"",
          "} else {",
          "  foreach ($sessionId in $matchingSessions) {",
          "    logoff $sessionId /server:localhost",
          "    Write-Output \"Logged off session ID: $sessionId\"",
          "  }",
          "}"
        ]
      }
    }
  ]
}

As you would notice, #2 would also allow for a quick termination of an active RDP session by the user. 

In this example, the broker provides the necessary parameters such as the domain and sure information, and the instance ID to run this document on. 

In another blog, we will look at how this solution can be extended to grant access to multiple servers at the same time. For more details on this integration and to explore detailed scripts, visit our GitHub page

Want to learn more about how Britive and AWS work together to eliminate static access risks? Register for our upcoming joint webinar to discuss how we scaled zero standing access for a Fortune 500 global financial institution