June 16, 2020 · How-To ·

SSH User Certificates With Azure AD & Smallstep

As I work through evaluating better security for infrastructure within my team, one of the areas I saw an opportunity ripe for automation is implementing SSH certificates. SSH certificates can provide a smoother experience than simple RSA keys, but normally require some specific domain knowledge about PKI. Certificates and PKI can be complicated; sometimes they create more headaches than they solve.

Enter Smallstep – they have created a great tool called step-ca for creating a really simple certificate authority and an excellent CLI called step for interacting with it. If you configure step-ca as a certificate authority for SSH, like so:

step-ca init -ssh

then it can issue both user and host certificates for use in your environment. Once you have a working CA, you can configure your ca.json with a new provisioner. Provisioners are the backbone of step-ca; they are how one is authorized to generate a certificate. Smallstep has built out an OIDC (OpenID Connect) provisioner which works with both Google and Azure AD.

[Note: Azure AD is the DaaS offering from Microsoft which is not the same as traditional Active Directory or ADFS.]

To set up an Azure AD provisioner, you'll need to first register Smallstep in your Azure AD tenant as an application. This can be done from the Azure CLI:

az ad app create --display-name "Smallstep SSH" --reply-urls https://garrettyamada.com:10000

[Replace "garrettyamada.com" with here. My static site generator likes to replace any instance of it with my domain name (oops).]

The port 10000 is an example specific listening port when the step CLI launches a web browser tab for sign-in. This can be set in our ca.json, as we'll see in a moment. For specifics on the app registration and the credential details you need, see https://smallstep.com/docs/sso-ssh/azure-ad/.

After the app is registered, we'll add a provisioner to our step-ca configuration's ca.json.

	"type": "OIDC",
	"name": "AzureAD",
	"clientID": "your-app-id",
	"clientSecret": "your-client-secret",
	"configurationEndpoint": "https://login.microsoftonline.com/your-tenant-id/v2.0/.well-known/openid-configuration",
	"admins": [
		"[email protected]"
	"domains": [
	"listenAddress": ":10000",
	"claims": {
		"maxTLSCertDuration": "8h0m0s",
		"defaultTLSCertDuration": "2h0m0s",
        "disableRenewal": true,
        "enableSSHCA": true

Once ca.json is updated, restart step-ca. Then, from the client machine (assuming you have bootstrapped step), run:

step ssh login [email protected] --provisioner "AzureAD"

This will launch a web browser tab, you'll sign in to Azure AD, which will return a token to step. step will use that token to request an SSH certificate from your CA, and if granted, add the certificate to your ssh-agent.

That's all there is to it for setting up user certificates with the Azure AD provisioner. For more details, see the Smallstep documentation. Happy SSH-ing!