When it comes to secure shell (SSH) authentication, there is a widespread consensus that SSH certificates hold an edge over SSH keys (though SSH keys are currently more widely used). SSH keys are easy to provision, but are hard to distribute and invalidate. SSH certificates, on the other hand, are easier to use and audit, but harder to provision. Happily, Platform.sh has made provisioning certificates easier for our users.
At Platform.sh, we use Secure Shell (SSH) certificates to authenticate users into their applications’ servers. We rely on a service named “Certifier” to provide the certificates. Certifier is, in essence, pretty simple:
It exposes an endpoint with the list of the certificate authority's public keys.
It exposes an endpoint that you can POST to with a public ssh key and then returns an SSH certificate that is valid for one hour.
The flow is mostly transparent thanks to some tricks in the ~/.ssh/config
file, such as:
Match host "*.platform.sh" exec "platform ssh-cert:load"
In this example, the platform ssh-cert:load
command is fetching a new SSH certificate.
Effectively, this lets us provide a mostly transparent workflow. Our customers run their SSH commands, and Certifier automatically grabs a new SSH certificate every time one is needed. Given that each certificate is only valid for one hour, if a customer needs to offboard a user, we just need to ensure that Certifier is no longer delivering certificates to that user.
Speaking of which, how does Certifier authenticate that user? It's obviously not just blindly returning SSH certificates to whomever is asking for one. Certifier is relying on one of the most prominent authentication technologies on the web: OAuth2.
When a Platform.sh customer logs in or tries to SSH, they’re effectively fetching an SSH certificate while passing along an OAuth access token that they previously obtained from our Authentication service. Certifier uses that token to get information about the customer from the OAuth token introspection endpoint(https://auth.api.platform.sh/oauth2/tokens
).
As an example, this is what the introspection endpoint can return:
$ curl https://auth.api.platform.sh/oauth2/tokens/"$(platform auth:token)"
{
"amr": [
"sso",
"mfa"
],
"auth_time": 1601545043,
"exp": 1601571772,
"grant": "refresh_token",
"iat": 1601570871,
"iss": "https://auth.api.platform.sh",
"jti": "<redacted>",
"nbf": 1601570871,
"ns": "platformsh",
"sub": "<redacted>",
"active": true,
"scope": "offline_access",
"client_id": "platform-cli",
"grant_type": "refresh_token",
"mfa_verified": 1601545043,
"expires": 1601571772,
"user_uuid": "<redacted>",
"access_token": "<redacted>"
}
By using this endpoint, Certifier can put the following metadata in the SSH certificate before signing it:
- The Universally Unique Identifier (UUID) of the user
- Whether and when the user used Multi-Factor Authentication (MFA) when logging in
With all that said, with all this information available for any system, such as the edge layer accepting SSH connections, Certifier can:
- Periodically fetch the certificate authority's certificates.
- Verify an SSH certificate coming in, trusting the metadata, such as the user's UUID, that is in the certificate.
In practice, we can put even more data on the certificates; that's what we're doing for the Platform.sh staff. For example, when a Platformer connects with administrative privileges, the certificate embeds some information such as:
- The region for which the certificate was requested. If the edge layer is not on the given region, it can reject it.
- The support ticket for which the certificate was requested. The edge layer can then log it to have thorough auditing.
Essentially, using short-lived SSH certificates with Certifier gives Platform.sh customers the best of all worlds:
- There's no need to maintain any certificate revocation lists.
- There's no need to rely on users rotating their credentials.
- You can use your usual Single Sign On-based OAuth servers for authentication.
- You can embed a ton of authentication/authorization related metadata.
Thanks to Certifier, Platform.sh customers can have transparent, secure, and keyless SSH connections using our Platform.sh CLI. You can also mandate multi-factor authentication for all of your projects. These are all things that will make your compliance officers happy. And we are all about making people happy.
(For additional information on using keys to authenticate users and devices, please read “What is PKI?”)