Service account keys aren’t like AWS access keys
AWS lets us use access keys to authenticate programmatically. That’s useful for local development, or if we want to let tools access AWS on our behalf. The closest thing to access keys on Google Cloud seem to be service account keys. But are they really that similar?
AWS access keys and service account keys have a number of things in common: We can create them to let applications or tools authenticate in an unattended way, and we can revoke them once we don’t need them anymore. For both keys, it’s also a good practice to rotate them periodically.
But there are also some key differences.
One difference is technical: An access key is a shared secret that’s used for symmetric encryption – or, more precisely, to create HMACs for request signatures. In contrast, a service account key is an RSA private key and we use that to generate RSA signatures. This difference might be interesting, but isn’t that relevant in the end – the fact remains that both keys are a form of secret, and must be treated as such.
More importantly, the two kinds of keys differ in their lifecycle and how they relate to user accounts:
- AWS access keys belong to an IAM user, and their lifecycle is tied to that IAM user. After an employee leaves the organization (or is let go), we disable their IAM user and that automatically revokes all their AWS access keys.
Service account keys belong to a service account, and service accounts have a lifecycle that’s disconnected from user accounts.
Let’s say the user [email protected] creates a service account along with a service account key. Some time later, Bob leaves the company and we disable his user account. Now Bob can’t authenticate anymore – but the service account and service account key continue to work! And if Bob still has a copy of this service account, then he can still use it.
AWS access keys belong to a user, and are meant to be used by that user. So it’s acceptable to store a copy of AWS access keys on our local workstation as long as we secure them appropriately. But the same isn’t true for service accounts: Service accounts don’t belong to any user, and they’re meant to be used by applications and background processes, not by human users. Allowing users to store service account keys on their computer is dangerous… and almost always unnecessary.
What is the closest thing to AWS access keys then, if not service account keys?
The closest thing to AWS access keys on Google Cloud are OAuth refresh tokens. Like AWS access keys, refresh tokens…
- are valid until revoked (unless we restrict their lifetime),
- have the same access to resources as the user (unless we restrict their scope),
- can be revoked (by the owning user or an admin),
- are tied to the lifecycle of the user account, and therefore
- are automatically revoked when we suspend or delete the user account.
Because the lifecycle of refresh tokens is tied to a user account, it’s safe to store refresh tokens locally on our workstation – as long as we store them in a secure location.
If we let local applications or tools like terraform
authenticate using a refresh token,
then any API calls they make are done on behalf of us, not on behalf of some service account.
For the majority of use cases, especially for local development, this works fine. And in the rare case
where we need to call an API that requires us to authenticate using a service account, we can
use impersonation.