How to Manage Access to SSH Resources

Twingate can work in conjunction with a Certificate Authority such as Smallstep to provide application-layer authentication to systems such SSH servers, web applications and databases including PostgreSQL, MySQL and MongoDB.

This capability augments the existing network level protections that Twingate offers to keep private resources invisible on the Internet and provide least privilege access to network resources.

For more information please refer to our blog post: The Many Layers of Zero Trust.

Smallstep’s blog post on this topic is very informative and helpful as well: DIY Single Sign-On for SSH


In this guide, we will configure Twingate to work with the open source version of Smallstep to provide secure SSH access in an AWS environment. Like Twingate, Smallstep is not limited to AWS and can work in any on-premises or cloud network including Azure, GCP and OracleCloud.

More specifically, in this guide we will use Pulumi to:

  • Set up an AWS VPC with:
    • an internet gateway
    • a public subnet
    • a private subnet
  • Deploy 2 EC2 instances with Twingate Connectors into the public subnet in accordance with our best practices
  • Deploy a Smallstep Certificate Authority onto an EC2 instance in the private subnet
  • Create an AWS Route53 Private Hosted Zone so we can connect to our servers using friendly domain names
  • Create a Twingate Remote Network and include Resources for:
    • Twingate Connectors (so we can SSH into them - also using a certificate)
    • Smallstep CA (so only our users can access Smallstep)


  • AWS CLI installed and configured (see here for instructions) or an AWS CloudShell.
  • Pulumi CLI installed and configured (see here for instructions)
  • Twingate API token with (Read/Write and Provision permissions)
  • Git (see here for instructions)
  • Twingate Client installed
  • Access to an OAuth 2.0 server. For this example we will use Google Cloud.
  • An AWS SSH Keypair to remotely SSH in case there are any problems.

Infrastructure setup

  • Clone the example repository by running: git clone cd pulumi-twingate-smallstep

  • Create OAuth credentials - if using GCP, create Desktop app credentials here and make a note of the Client ID and Client Secret.

  • Create Pulumi stack:

    • pulumi stack init dev - we will create a stack named dev
    • cp ./Pulumi.example.yaml ./ - we will copy the example variables over
    • Set the Client ID and Client Secret from Step 2 as well as the Twingate Network name and API token (replace the values in capital letters with your values)
    # OAuth2 credentials
    pulumi config set --path ca_config.ca_oauth_client_id "CLIENT_ID"
    pulumi config set --secret --path ca_config.ca_oauth_client_secret "CLIENT_SECRET"
    # Only OAuth2 subjects (users) that have accounts with the domain name below can connect
    # set to the domain name of your organisation
    pulumi config set --path ca_config.ca_oauth_allowed_domain "YOUR_DOMAIN_NAME"
    # Twingate API token and network name
    pulumi config set twingate:apiToken TWINGATE_API_TOKEN --secret
    pulumi config set twingate:network TWINGATE_ACCOUNT_NAME
    # Set your email address for the Certificate Authority
    pulumi config set --path ca_config.ca_email "YOUR_EMAIL_ADDRESS"
    # The name of an AWS SSH keypair to create instances with
    pulumi config set --path data.key_name "SSH_KEYPAIR_NAME"
  • pulumi up - deploy the example to your AWS environment

  • Now that the infrastructure has been deployed, we can test the SSH connection using Twingate for network access and SmallStep for SSH credentials.

  • Log in to the Twingate Admin Console at and then navigate to the Twingate Connector Resource in the smallstep_demo Remote Network that has been created by Pulumi. Grant your user access to it. Unless the configuration was altered, the name should be in the form

  • Install the step CLI (see here for more details):

    • On MacOS: brew install step
    • On Ubuntu Linux: sudo wget && sudo dpkg -i step-cli_amd64.deb
    • On Windows (via Winget) winget install Smallstep.step
  • Log in to your Twingate Client on your machine.

  • Now, we are ready to test the SSH connection. For this example we will SSH into the Connector host, but in practice it can be any SSH host on your Network.

  • The open source version of Smallstep does not manage user accounts on the SSH hosts. This means that if you have an email such as you will manually need to create a user account for charles on the SSH host: ssh -i ./path/to/your/keypair.pem

Using the AWS SSH keypair, SSH into your Connector host and execute sudo adduser --quiet --disabled-password --gecos '' YOUR_USERNAME . 11. We need to configure our local machine to trust the CA certificate. For this, we will obtain the certificate and implicitly trust it. (In a production setting you will want to transmit the root certificate to the Client via an alternative approach such as an MDM,) For demo purposes, on your Client machine you may inspect and execute: ./ 12. At a command prompt try to SSH into the connector host using SmallStep to generate a short-lived certificate using the OAuth2.0 provider we configured earlier:

step ssh login YOUR_USERNAME@YOUR_DOMAIN --provisioner "Google"
step ssh config
step ssh hosts

Now you can log in using ssh Smallstep will use the short-lived SSH certificate obtained via OAuth authentication.

Further information

Smallstep offer a managed service so users do not need to run a Certificate Authority and do not need to manually add and remove users from SSH hosts. For more information, see Smallstep SSH.

Last updated 8 days ago