A zero-trust shell, built from AWS building blocks

Figma's production infrastructure used to rely on SSH through bastion hosts—a common setup, but one that becomes a management burden as a company scales and a tempting target for attackers. In mid-2020, the security team set out to replace it with a zero-trust shell access system built on AWS SSO and Systems Manager. The goals: smooth user experience, phishing-resistant MFA, short-lived credentials, centralized auditing, minimal operational overhead, and a rollout that wouldn't disrupt existing workflows.

The team first evaluated commercial options like Okta Advanced Server Access, but found them insufficiently flexible for existing use cases and potentially costly at Figma's scale. Adding an external dependency for such a critical workflow also raised availability concerns. Since Figma's infrastructure was already deeply integrated with AWS, the team explored a proof-of-concept using AWS components as building blocks.

The core: Session Manager

AWS Systems Manager's Session Manager provides shell access to EC2 and ECS instances without requiring them to expose an SSH port or be reachable from external networks. The feature manages authenticated, encrypted TLS connections between an agent on the managed instance and the user's client—whether the AWS console or a CLI tool. Session Manager supports running commands, interactive shells, and even tunneling SSH sessions. Permissions are centrally managed via IAM roles assumed by human users who authenticate through AWS SSO.

For authentication, Figma uses Okta with AWS SSO, enforcing device trust and WebAuthN for MFA. After authentication, users assume a dedicated, minimally privileged IAM role with short-lived tokens to start a session. Session transcripts are sent to an encrypted S3 bucket, and because session IDs are logged alongside SSO role usernames, individual actions can be traced back to specific users.

One risk to note with AWS SSO is device code phishing: an attacker can generate their own device authorization URL and trick a victim into authorizing it, thereby obtaining an access token. While engineers should find an unprompted SSO page suspicious, Figma added monitoring and alerts as an extra layer of mitigation.

Integrating Okta with AWS SSO using group push was straightforward, letting the IT team manage access control via Okta groups. Users who prefer a web experience can start using Session Manager directly in the AWS Systems Manager console; terminal users get a purpose-built CLI tool.

Configuration guidance

IAM policies

Session Manager uses distinct IAM permission sets for user roles and target resources, enabling minimally privileged policies scoped to specific targets. For EC2, the instance needs permissions to create and open SSM message channels while the user role needs SSM session permissions on that instance. For ECS, the task definition requires SSM message channel permissions and the user role needs ExecuteCommand permissions on the target container. ECS also requires a dedicated KMS CMK with permissions set to encrypt session logs.

Guardrails and defense in depth

Restrict IAM permissions to access or modify SSM documents such as SSM-SessionManagerRunShell or AWS-StartSSHSession to prevent users from obtaining a shell or tunneling SSH. If users only need specific commands, SSM RunCommand can provide safe, one-off invocations instead of a full interactive shell—Figma uses this in its deploy process to replace operations previously done via SSH keys in scripts.

For EC2, configure the username and sudo permissions of the system account being logged into. Shell profiles are worth customizing since users land in a bare Bourne shell by default, without their usual environment.

Logging and sensitive data

Logs can be sent to an encrypted S3 bucket or CloudTrail. Figma sends logs to a separate account, enforces encryption and deletion prevention via Service Control Policies, blocks public access, and monitors read attempts. Be aware that SSM logs all shell output, which may contain secrets—plan accordingly.

Securing Session Manager even if you don't use it

Because aws-ssm-agent is pre-installed on many AMIs, any IAM principal with sufficient Session Manager permissions could get a shell on an instance despite no configured network access. That makes it an attack surface worth locking down regardless of whether you use the feature. Recommended mitigations:

  • Audit whether any IAM users hold Systems Manager permissions; prefer migrating away from long-lived IAM users entirely.
  • For human users, grant minimal Systems Manager permissions to only the IAM roles that need them, limit session duration, and restrict which instances can be connected to. Be wary of default AWS SSM IAM policies—some grant extremely broad permissions, including full S3 access.
  • Similarly, grant only necessary Systems Manager permissions in instance or task definition IAM policies.

The CLI experience

For terminal users, Figma configured a seamless flow between web-based SSO and CLI tools. The AWS CLI can automatically open a browser page to complete the SSO flow when credentials are needed and return credentials to the CLI. Combined with a tool like aws-vault for secure temporary credential management, starting a shell session is scriptable. SSH for EC2 can also be routed through Session Manager as a proxy by adding entries to ~/.ssh/config.

The response from engineers was positive. As one Figma engineer put it: “[This] is really fun to use. I wish all security measures were so low-friction.”

Migration without disruption

Forcing immediate architectural changes would have disrupted workflows that depended on SSH, so Figma chose a gradual rollout. SSH remained functional, but only when tunneled through Session Manager. This preserved the familiar user experience while adding an SSO requirement and ensuring that possessing an SSH key alone no longer granted access.

During a transition period of several weeks, both tunneled SSH (SSH over SSM) and classic non-tunneled SSH were permitted, giving teams time to adjust. After the deadline, all inbound internet connections to bastions were blocked, making Session Manager the sole entry point for shell access. To guard against potential SSM failures, a small set of engineers retains the ability to lift these blocks in a break-glass scenario, with alerts triggered automatically.

Replacing SSH entirely

Tunneled SSH still had a limitation: Session Manager acts only as a transport wrapper, so full session transcripts of the encrypted SSH traffic are unavailable. This required supplementary tooling for auditing connections. Figma eventually addressed this by retiring tunneled SSH in favor of a simple script that acts as a drop-in replacement for SSH.

The script uses the AWS CLI to invoke either aws ssm start-session for EC2 instances or aws ecs execute-command for ECS instances. This approach extends to containers—where SSH does not—and lets developers switch between profiles in the multi-account AWS environment. The script is now the standard method for engineers to obtain shell access securely.

Broader adoption and benefits

Built on native AWS services, the new system replaces the legacy bastion design and reduces operational overhead for infrastructure and IT teams. Other Figma infrastructure projects, such as deployment tools, have since adopted components of this design, using SSM RunCommand instead of SSH scripts to enhance security.