Tom's Blog

OS Login in GCP for Ansible

Considering the many ways you can authorize users to access the cloud machines you usually want to stick to a default approach and maybe even one which is endorsed by your cloud provider. In my case it is GCP and OS Login which allows project users to login by just using there account mail and credentials. Awesome! But how can we give an service account access to these machines?

First of all, I would have spent many more hours trying to get this feature working, if it weren’t for this blog post by Alex Dyzoba. But let’s get to it right away. To enable OSLogin for a single machine make sure to set the metadata key enable-oslogin to TRUE in the instance’s settings.

Next, we want to make sure that the service account which is trying to login to the machine has the required roles set.

Roles

With the following command, we can list all the roles assigned to a certain account.

gcloud projects get-iam-policy example-project-123456  \
    --flatten="bindings[].members" \
    --format='table(bindings.role)' \
    --filter="bindings.members:your-service-account@example-project-123456.iam.gserviceaccount.com"

ROLE
roles/compute.admin
... (any other role which is assigned to the service account)
roles/iam.serviceAccountUser

To follow the principle of least privilege we will remove the roles/compute.admin role.

Above we can see that the service account also has the roles/iam.serviceAccountUser role assigned to it. What this role enables the user to do is explained in the documentation:

Granting the Service Account User role to a user for a project gives the user access to all service accounts in the project, including service accounts that may be created in the future.

From my understanding, this will allow our service account to impersonate another service account in the project. As such if there exists a service account which can log in into the machine it will use it. According to the GCP documentation for OSLogin, this role is required for service accounts as well as users to be able to login to an instance if the service account for the machine is not set to None.

Now we also need to grant the role/compute.osAdminLogin role to our service account. Granting this role on a project level would enable the account to log into any machine which has OSLogin enabled. We could do this, but we want to keep the scope as small as possible. Therefore we will bind the role to a specific instance.

gcloud compute instances add-iam-policy-binding INSTANCE-NAME --zone us-central1-a --member serviceAccount:your-service-account@example-project-123456.iam.gserviceaccount.com  --role roles/compute.osAdminLogin

# To revoke the IAM binding
gcloud compute instances remove-iam-policy-binding INSTANCE-NAME --zone us-central1-a --member serviceAccount:your-service-account@example-project-123456.iam.gserviceaccount.com -role roles/compute.osAdminLogin

With this, the service account can only log in to the specified instance and no other one.

Upload SSH keys

Next, we need to create and then upload an ssh key pair which will be linked to the service account for the OSLogin. With the command below we generate a key using an elliptic curve algorithm and save it as sa-oslogin-key(.pub) without a password.

ssh-keygen -t ed25519 -f sa-oslogin-key -N ""

Now we need to make sure that on our machine we are switching to the service account to not modify the SSH keys of our developer account. For this, we can use the JSON key file which e.g. can be downloaded via the web console of GCP.

gcloud auth activate-service-account --key-file=your-service-account.json

Next, we can add the previously generated ssh key.

gcloud compute os-login ssh-keys add --key-file=sa-oslogin-key.pub

Actually logging in

From the beginning of the blog post up until here we have mentioned the word login 16 times. Now let us finally log in to a machine, which should be straight forward and easy from now on, right? Well almost, we are still missing the username for the service account. But from the previous command which added the ssh key, we should see the username displayed under the key username under posixAccounts. With this username we can now ssh into the machine as follows:

ssh -i sa-oslogin-key sa-username-here@public-ip