GCP OS Login Explained: IAM-Based SSH Access for Compute Engine
OS Login ties SSH access to Google identities and IAM roles instead of static key files stored in VM metadata. When someone needs VM access, you grant them a role. When they leave, you remove it. That change takes effect across every VM in the project immediately. This page explains what OS Login is, how it works, the roles involved, how to enable and roll it out safely, and how it compares to the traditional SSH key metadata approach.
What is OS Login?
OS Login is a Compute Engine feature that replaces SSH key management in VM metadata with centralised IAM-based access control.
With the traditional approach, you store SSH public keys in VM metadata: either at the project level (which applies to every VM) or at the instance level (per VM). Managing those keys across many VMs and many team members becomes messy. When someone leaves, you have to find and remove their key from every place it was added.
OS Login works differently. Access is controlled by IAM roles assigned to
Google identities (user accounts or service accounts). When a user with the
right IAM role runs gcloud compute ssh,
GCP validates their identity and IAM permissions in real time, creates a
Linux user account on the VM automatically, and establishes the connection.
No keys need to be manually distributed, and no metadata needs to be
edited on individual VMs.
Think of SSH key metadata like physical door keys. You cut copies, hand them out, someone leaves the team, and you have to track down every copy and change the locks on every door. OS Login is like replacing all those locks with a keycard system. Access is managed from one panel. Cancel a card and that person is locked out instantly, on every door, with no physical key changes needed.
Why OS Login exists: the SSH key management problem
SSH key metadata access works well for a single developer on a personal project. It starts to break down the moment a team is involved.
Key sprawl. As the team grows, keys accumulate in project metadata and get added to individual VMs. There is no central view of who has access to what.
Offboarding is manual and error-prone. When a team member leaves, someone must remember to remove their key from project metadata and from every instance it was added to individually. A missed key means stale access.
No automatic audit trail. Metadata-based SSH access does not produce a log entry per connection in the same structured way OS Login does. You cannot easily audit who connected to which VM and when.
Inconsistent access scope. Project-level keys grant access to every VM in the project by default, which is wider than most users should have. Scoping access per VM using metadata requires editing each VM individually.
OS Login addresses all of these by moving access decisions into IAM, where they are already centralised, auditable, and consistently enforced.
How OS Login works
Think of it like a bouncer with a live digital list instead of a pile of printed invitations. With metadata keys, the bouncer checks if you have the right physical key. With OS Login, the bouncer checks a live database on every attempt. If your name was removed an hour ago, you are not getting in, even if you still have the old key in your pocket.
When a user runs gcloud compute ssh on a VM with OS Login
enabled, the following happens:
GCP checks whether the user has
compute.osLoginorcompute.osAdminLoginpermission on the instance or the project it belongs to.If the permission is present, GCP looks up or creates a POSIX user account on the VM tied to the user’s Google identity. The Linux username is derived from the user’s Google account.
The SSH connection is established using the user’s OS Login profile keys (SSH public keys stored in the OS Login profile, not in VM metadata).
The connection is logged in Cloud Audit Logs under the
compute.googleapis.comservice: who connected, to which VM, and when.
When you remove the user’s IAM role binding, the permission check fails on the next connection attempt. Access is revoked immediately. No key cleanup required. The Linux user account remains in the OS, but the user cannot authenticate without the IAM role.
When OS Login is enabled on a VM, project-level SSH key metadata and per-instance SSH key metadata are both ignored. Keys stored directly in VM metadata no longer grant access.
Required roles and permissions
Two roles control OS Login access. Both are part of the Compute Engine IAM role set:
roles/compute.osLogin: grants SSH access as a standard Linux user. The user can log in and run commands but does not havesudoprivileges.roles/compute.osAdminLogin: grants SSH access withsudoprivileges. This gives the user effective root access on the VM.
Granting roles/compute.osAdminLogin to a whole team or at the
project level is one of the most common OS Login mistakes. This role gives
sudo access on every VM in scope. Most developers, analysts,
and operators only need roles/compute.osLogin. Treat
osAdminLogin like a master key: assign it to specific people
on specific machines only.
Both roles can be granted at the project level (applies to all VMs in the
project) or at the instance level (applies to one VM only). Instance-level
grants are preferable for developers who only need access to specific VMs.
Project-level grants suit administrators who need broad access, but even
then, use osLogin rather than osAdminLogin unless
root access is genuinely required.
If a VM has a service account attached and the connecting user does not
already have roles/iam.serviceAccountUser on that service
account, GCP may block the SSH connection. This prevents privilege
escalation via the instance’s attached identity. Grant the role on the
specific service account, not at the project level, to keep the scope
narrow. See
least privilege for the
reasoning behind this.
Users also need permissions to look up instance metadata when using
gcloud compute ssh. roles/compute.viewer or a
custom role with compute.instances.get is typically sufficient
alongside the OS Login role.
# Grant standard SSH access at the project level
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=user:alice@example.com \
--role=roles/compute.osLogin
# Grant sudo SSH access at the project level
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=user:bob@example.com \
--role=roles/compute.osAdminLogin
# Grant SSH access on a single VM only (instance-level)
gcloud compute instances add-iam-policy-binding my-vm \
--zone=us-central1-a \
--member=user:alice@example.com \
--role=roles/compute.osLogin
# Revoke access immediately (no key cleanup needed)
gcloud projects remove-iam-policy-binding PROJECT_ID \
--member=user:alice@example.com \
--role=roles/compute.osLoginFor teams managing a lot of OS Login bindings via code, see managing IAM with gcloud. For fine-grained access that varies by environment or time window, see IAM conditions.
How to enable OS Login
OS Login is enabled through metadata, not through the IAM console. You can set it at the project level (applies to all VMs) or at the instance level (applies to one VM and overrides the project setting).
# Enable OS Login for all VMs in a project
gcloud compute project-info add-metadata \
--metadata=enable-oslogin=TRUE
# Enable OS Login on a specific VM only
gcloud compute instances add-metadata my-vm \
--zone=us-central1-a \
--metadata=enable-oslogin=TRUE
# Override to keep key-based access on a specific VM
# even when OS Login is enabled project-wide
gcloud compute instances add-metadata my-vm \
--zone=us-central1-a \
--metadata=enable-oslogin=FALSEInstance-level metadata always takes precedence over project-level
metadata. A VM with enable-oslogin=FALSE in its own metadata
continues to use key-based access even when OS Login is enabled
project-wide.
Rolling out safely to an existing team
Enabling OS Login project-wide on an existing environment immediately disables all project-level and per-instance SSH key metadata access on every VM that does not have an instance-level override. Anyone who relied on those keys will lose SSH access until they are granted the correct IAM role. Grant the roles first, test on one VM, then roll out.
A safe rollout sequence:
Identify every user with current SSH access and determine which IAM role they should receive.
Grant each user the appropriate role (
osLoginorosAdminLogin) before making any metadata change.Enable OS Login on a single test VM using instance-level metadata and verify each user can still connect.
Once verified, roll out project-wide. Keep a break-glass account available during the transition.
How users add their SSH keys to an OS Login profile
Users can add SSH public keys to their OS Login profile. These keys are stored centrally in Google’s identity system, not in any individual VM’s metadata. Once added, a key works on any VM where that user has the OS Login IAM role. No per-VM key setup required.
This is one of the main practical advantages over metadata SSH keys: a developer with access to 20 VMs only needs to add their public key once. The key follows their identity, not the VM.
# Add an SSH public key to your OS Login profile
gcloud compute os-login ssh-keys add \
--key-file=~/.ssh/id_ed25519.pub
# List SSH keys currently in your profile
gcloud compute os-login ssh-keys list
# Remove a key by its fingerprint
gcloud compute os-login ssh-keys remove \
--key=KEY_FINGERPRINTEnforcing MFA for SSH
OS Login supports mandatory two-factor authentication (2FA) for SSH connections. When enabled, a successful IAM role check is not enough. The user must also complete a second factor: a TOTP code from Google Authenticator or a compatible app, or a hardware security key.
This is worth enabling in any environment where VMs hold sensitive data, are exposed to the internet, or need to meet a compliance requirement such as PCI-DSS, HIPAA, or SOC 2 that specifies MFA for privileged access.
# Enable OS Login with 2FA project-wide
gcloud compute project-info add-metadata \
--metadata=enable-oslogin=TRUE,enable-oslogin-2fa=TRUE
# Enable OS Login with 2FA on a specific VM
gcloud compute instances add-metadata my-vm \
--zone=us-central1-a \
--metadata=enable-oslogin=TRUE,enable-oslogin-2fa=TRUEFor internal development VMs behind a private VPC with IAP tunnelling already in use, 2FA adds friction without much extra security benefit. For internet-accessible or compliance-scoped production VMs, enable it as a default. See securing production systems for how this fits into a broader hardening checklist.
When to use OS Login
OS Login is the right default for most team-managed Compute Engine environments. It fits cleanly when:
Multiple people need VM access. Even with two developers, centralising access control in IAM is cleaner and safer than passing keys around.
People join and leave the team regularly. OS Login makes onboarding and offboarding instant and complete. A removed IAM binding revokes all VM access in one command.
You have many VMs. Managing per-VM SSH key metadata at scale is fragile. OS Login lets the IAM policy do the heavy lifting.
Audit logging matters. Every OS Login SSH connection appears in Cloud Audit Logs automatically. Key-based metadata access does not produce the same structured audit trail.
Compliance or production requirements. Most security frameworks expect centralised access management, evidence of revocation, and logs of who accessed what. OS Login satisfies all three.
You use service accounts alongside human access. OS Login integrates naturally with the IAM model you are already using for service accounts and other GCP resources.
If your team already uses Google Workspace or Cloud Identity, OS Login costs nothing extra to set up. The identity infrastructure is already in place. You only need an IAM role binding and the metadata flag.
When OS Login may not be your first priority
If you are spinning up a personal sandbox VM for a learning lab or a quick test, key-based metadata access is faster to set up and perfectly adequate. OS Login adds the most value in team, production, or compliance-sensitive contexts. For a single-developer personal project, the overhead of IAM role management may outweigh the benefit.
For all the SSH options available in Compute Engine, including IAP tunnelling and when to use each, see SSH access in Compute Engine.
OS Login vs SSH keys in metadata
Both approaches let users SSH into Compute Engine VMs. The differences matter when operating at team scale or under security requirements.
| Aspect | SSH key metadata | OS Login |
|---|---|---|
| Access control model | Static SSH keys stored in project or instance metadata | IAM roles on Google identities, checked at connection time |
| Revocation | Manual: find and remove the key from each location it was added | Instant: remove the IAM role binding. Takes effect immediately. |
| Auditability | No structured per-connection audit log by default | Every SSH connection logged in Cloud Audit Logs automatically |
| Onboarding a new user | Add their public key to project metadata or each required VM | Grant the IAM role at project or instance level. Done. |
| Access scope control | Project keys apply to all VMs; per-VM keys require per-VM edits | Grant at project or instance level, consistent with IAM everywhere |
| Scale across many VMs | Fragile; key sprawl grows with the fleet | Scales cleanly; IAM policy is independent of VM count |
| Risk of stale access | High; unused keys are not automatically cleaned up | Low; access reflects the current IAM state, not historical key additions |
| MFA support | Not available via metadata keys | Available via enable-oslogin-2fa=TRUE |
| Setup complexity for a single developer | Low; gcloud handles key generation automatically | Slightly higher; requires an IAM role grant before connecting |
Common beginner mistakes
Enabling OS Login project-wide without migrating existing users first. When OS Login is enabled, all project-level and instance-level SSH key metadata is ignored immediately on affected VMs. Anyone relying on those keys loses access until they are granted an IAM role. Grant the roles first, test with one VM, then enable project-wide.
Granting
compute.osAdminLoginto everyone. Admin login givessudo(root) access on the VM. Most developers and analysts only needcompute.osLogin. Following least privilege means giving admin access only to the specific people who genuinely need root on a specific machine.Granting OS Login roles at the project level when instance-level is more appropriate. A project-level
osLogingrant gives SSH access to every VM in the project. If a developer only works with one or two VMs, bind the role at the instance level to limit exposure.Forgetting the instance-level metadata override. A VM with
enable-oslogin=FALSEin its own metadata will keep using key-based access even if you have enabled OS Login project-wide. Check per-VM metadata if a VM is not behaving as expected after enabling OS Login.Not testing access after rollout. Enable OS Login on one VM, verify that each affected user can connect, and only then roll out project-wide. Skipping the test step is how teams lock themselves out of production.
Overlooking the
iam.serviceAccountUserrequirement. If the VM has a service account and the connecting user does not haveroles/iam.serviceAccountUseron it, the SSH connection can be blocked as a privilege escalation prevention measure. Grant this role on the specific service account, not project-wide.
Summary
- OS Login replaces SSH key metadata with IAM-based access control tied to Google identities
- Enable with
enable-oslogin=TRUEin project or instance metadata; instance metadata overrides project metadata roles/compute.osLoginfor standard SSH access;roles/compute.osAdminLoginfor sudo. Follow least privilege.- Users store SSH keys in their OS Login profile once; those keys work on any VM where they hold the role
- Access is revoked instantly by removing the IAM binding. No key cleanup required.
- Every connection is logged in Cloud Audit Logs automatically
- Add
enable-oslogin-2fa=TRUEfor SSH MFA enforcement on sensitive or internet-facing VMs - Roll out carefully: grant IAM roles before enabling OS Login to avoid locking out existing users
Frequently asked questions
What is OS Login in GCP?
OS Login is a Compute Engine feature that replaces static SSH key metadata with IAM-based access control. Instead of storing SSH keys in VM metadata and managing them manually, you grant a Google identity the roles/compute.osLogin or roles/compute.osAdminLogin role. GCP then creates a Linux user account on the VM automatically and manages authentication. Every SSH connection is logged in Cloud Audit Logs.
What is the difference between compute.osLogin and compute.osAdminLogin?
compute.osLogin grants SSH access as a standard Linux user with no sudo privileges. compute.osAdminLogin grants SSH access with sudo (root) privileges. Most developers only need osLogin. Reserve osAdminLogin for administrators who genuinely need to run privileged commands on the VM — granting it broadly is a common least-privilege mistake.
Does OS Login replace SSH keys completely?
When OS Login is enabled on a VM, project-level SSH key metadata is ignored entirely, and per-instance SSH key metadata is also ignored. Users can still store SSH public keys in their OS Login profile (not in VM metadata), and those keys are used during OS Login authentication. If you need to keep key-based metadata access on a specific VM, you can override OS Login at the instance level with enable-oslogin=FALSE.
Can I enable OS Login on only some VMs?
Yes. Setting enable-oslogin=TRUE in project metadata enables it for all VMs in the project by default. You can override this per VM using instance-level metadata. Set enable-oslogin=FALSE on an individual VM instance to keep key-based metadata access on that VM while the rest of the project uses OS Login. This lets you migrate gradually.
Should I use OS Login for production Compute Engine instances?
Yes. For any environment with more than one person accessing VMs, OS Login is the cleaner and safer approach. It eliminates SSH key sprawl, centralises access decisions in IAM, makes offboarding instant, and automatically produces an audit trail in Cloud Audit Logs. For a personal sandbox lab, key-based access is simpler to set up, but for team or production use, OS Login is the right default.