Enabling just-in-time access to Google Cloud resources
The principle of least privilege states that we should grant users just enough access to carry out everyday activities, but no more. But what about the occasional case where a user does need privileged access, maybe to handle an incident or perform a rare configuration change?
If we grant users all the access they might ever need, then we’re violating the principle of least privilege. But not granting users privileged access at all isn’t an option either.
An effective approach to address this catch-22 is to use just-in-time access. The idea of just-in-time access is that we grant users a minimum level of access, and let them temporarily “elevate” their access when needed.
For just-in-time access to work effectively, 3 requirements must be met:
- Administrators must be able to define which roles and resources users should be eligible for just-in-time access.
- Just-in-time access must be time-bound and expire automatically.
- All just-in-time access must be audit-logged so that it can later be reviewed by administrators
If implemented properly, just-in-time access lets us:
- Apply the principle of least privilege, most of the time
- Reduce the risk of accidental production changes caused by fat-fingering
- Maintain an audit trail for privileged access
But how do we implement just-in-time access? On Azure, we can use
Privileged Identity Management,
which supports both self-elevation and multi-party approvals. On AWS, we can temporarily assume a role
(for example, by using aws sts assume-role
or SSO) to achieve something to a similar effect. But on Google Cloud, our options are a bit more limited:
- We can use delegated role granting to let users grant themselves additional roles when they need to. But the expressiveness of these IAM conditions is limited, and there is no way to enforce role grants to be time-bound. It’s also not possible to request users to provide a justification before they grant themselves additional roles, making auditing difficult.
- We can let users impersonate a service account, and grant the service account privileged access. But this only works for on the command line and can lead to either a proliferation of service accounts (where each service account grants access to a specific set of resources) or over-privileged service accounts (which have privileged access to many resources).
- We can provide users a second user account for privileged access ([email protected] and [email protected]). While this approach might be better than granting a user permanent privileged access, it can be unwieldy to manage and doesn’t satisfy any of the requirements outlined above.
Just-In-Time Access
To make managing privileged access on Google Cloud a little easier, I recently created Just-In-Time Access, an open-source application that lets us manage just-in-time privileged access to Google Cloud projects.
Just-In-Time Access introduces the notion of eligible role bindings to Cloud IAM. Unlike a regular IAM role binding, an eligible role binding doesn’t grant the user access to a project yet: Instead, a user first has to activate the binding on demand by using the Just-In-Time Access application. Activation is temporary and requires the user to provide a justification (like a bug or case number).
As an administrator, we can grant a role (to a user or group) and make it eligible by adding a special IAM condition to the IAM role binding:
has({}.jitAccessConstraint)
Instead of granting eligible access to individual users, we can also grant it to groups.
As a user, we can list the roles and resources we’re eligible to access by using the Just-In-Time Access application.
We can then activate one or more role bindings and provide a justification for doing so. Just-In-Time Access then grants is temporary access to the resource.
As an administrator, we can use Cloud Logging to review when and why eligible roles have been activated by users.
Deploying Just-In-Time Access
Just-In-Time Access is a Java application that’s designed to run in App Engine and uses Identity-Aware-Proxy for authentication and authorization. For details on deploying the application, see Manage just-in-time privileged access to projects.