Service account can create PubSub subscriptions but can't read from them - google-cloud-platform

I've created a service account I intend to use in our development environment, and since its credentials are checked into source control, I want to lock down its access to the bare minimum.
When spinning up new hosts, our app creates a new PubSub subscription, listens on the newly created subscription, then deletes it when finished. We chose this model over having a number of preconfigured/hardcoded subscriptions because the number of hosts scales up and down with time, we don't want host-specific config (In the form of a host-subscription map) if possible, etc. We want to have this same behavior in our local development environments ideally for debugging.
I created a specific "development" topic and granted our development service account the Pub/Sub Admin role, allowing it to attach subscriptions to that topic. I also granted the service account the project-level permission that allows it to create subscriptions. The service account can successfully create a new subscription and attach it to the topic, but when it tries to read from the new subscription, I receive a permission denied error.
I'm guessing this is because, when checking the newly created subscription, I notice that the service account that created it is not granted any permissions of any kind to that subscription. I would've expected the account that created a subscription to at least have read rights to it.
Is there a way for a service account to create subscriptions, attach them to a topic, and then read from that subscription... while not giving the service account access to any other subscriptions or topics? I'm aware I could just give the service account a "higher level" role with access to read all subscriptions, but that defeats the purpose of having a development-only account.

After your service account creates the subscription, it can call setIamPolicy on the subscription to grant itself read access to it. This works because you gave your service account the pubsub admin role on the project, which includes the ability to call setIamPolicy on any subscription in the project.
https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/setIamPolicy

Related

Restrict user access to a topic/subscription in google pub/sub

In my project, project A publishes a message and project B pulls it out of Google cloud. I have several B clients and want to limit them to a specific topic and subscription. I tried the IAM conditions but it does not work for pubsub and seems to be only for pubsub lite. Does anyone know how to restrict user access to a particular topic and subscription?
You can grant roles at different level:
Organization
Folder
Project
Resource
When you go to the IAM page, you grant at the project level and thus you have access to all the resources of the project.
You should be in this case where you grant a service account of the project B to pubsub role on project A. And thus the service account has access to all topics/subscriptions.
To solve this, you can only grant a service account on a topic or on a subscription (at resource level)
Go to the topic or subscription page
Tick the checkbox in front of the resource that you want
Go to the right, in the info panel, in the permission tab
Click on add member to grant a service account (or a user account) only on this resource
Alternatively, you can use the method projects.topics.setIamPolicy of the PubSub API to set permissions at the resource level.
If you don't want to call the API directly, you can also use CLI with this command
gcloud pubsub topics set-iam-policy TOPIC POLICY_FILE

GCP Pub/Sub default service account is not getting created when enabling the API

We have two projects in our GCP account; one for our Dev environment and one for our Test environment at the moment. Terraform manages most of our infrastructure, so we have minimal clicking around the GUI, or CLI commands.
I have assumed we enabled the Pub/Sub API by deploying to it with Terraform in both of our environments, although we may have needed to do this manually. We noticed that Google created a default Pub/Sub service account for us in our Dev environment, but not in our Test environment. This docs page suggests it should make this service account.
Additionally, we have noticed multiple Pub/Sub subscriptions working, apparently without any service account. We believe that the service account is only needed for this particular Subscription because it is a push to an e-mail server. Therefore, it needs a service account with the 'Service Account Token Creator' role.
We've attempted to redeploy the whole infrastructure and disable/re-enable the Pub/Sub API. Neither seemed to kick GCP into creating the Service Account. Further to this, we attempted to make the default service account manually. Still, GCP constrains the name a user can give a service account themselves, so we're unable to create a service account with the name that the Pub/Sub service would expect.
We wonder if there is some configuration of the project we may have missed or if anyone has seen this previously?
Does it not exist or does you not see it?
I'm pretty sure that it exists but without any role granted on it and you don't see it in the UI. Try to grant a role on this default service account, and it will appear in the IAM page!

Limiting the access to Google Cloud Platform Service Account to specific Gmail Accounts

I have recently made a program that listens to a PUB/SUB topic that is connected to a Gmail account. I have it all working fine. When a push notification arrives it will do different tasks based on the message content.
The problem is that I use a Service Account to connect to all the API's on Google Cloud Platform that I need. The Service Account allows access to ALL of our Gmail accounts in our organization. I need to somehow limit the access to a specific Gmail account.
The closest I could find to this issue was this question Impersonating list of users with Google Service Account. However, the only solution presented there was to turn my project into a marketplace app which I do not want to do.
I have tried setting up an Organizational Unit and trying to limit the scope to that somehow, but there seems to be know way (that I can find) to do it. I did try speak with Google Cloud Platform help but they didn't know the answer as it didn't quite fall under their area of expertise and referred me on to another help group, but I'm not eligible for them because I don't pay for support.
Edit: It doesn't actually appear that what I want to do is possible. I'll be going back to an OAuth2 method of authentication.
Understanding service accounts explains the possibilities:
Service accounts can be thought of as both a resource and as an identity.
When thinking of the service account as an identity, you can grant a role to a service account, allowing it to access a resource (such as a project).
When thinking of a service account as a resource, you can grant roles to other users to access or manage that service account.
Now try to fit that impracticable intent into there ...
If you need to limit the access of the service account to user-specific resources, this can only be done on the application level, not the system level - since a service account can impersonate just any user identity; eg. in order not to mess up the ownership, when uploading files on behalf of a user. If you want 1 user identity to access 1 user-specific resource, why even use a service account? And when using a service account, why not just impersonate as the correct identity? This could even be hard-coded, if it's only 1 user identity. But nevertheless, it can only be done on the application level - but cannot be configured for the service account itself.

Can't create job on GCP Cloud Scheduler

When I try to create a job in the GCP Cloud Scheduler I get this error:
{"error":{"code":7,"message":"The principal (user or service account) lacks IAM permission \"iam.serviceAccounts.actAs\" for the resource \"[my service account]\" (or the resource may not exist)."}}
When I enabled the GCP Cloud Scheduler the service account was created (and I can see it in my accounts list). I have verified that it has the "Cloud Scheduler Service Agent" role.
I am logged in as an Owner of our project. It is when I try to create the job that I get this error. I tried to add the "Service Account User" to my principal account, but to no avail.
Does anyone know if I have to add any additional permissions? Or if I have to allow my principal to act (impersonate?) this service account in some way?
Many thanks.
Ben
Ok I figured this out. The documentation is (sort of, in my view) clear if you read it in a certain way / know how GCP IAM works.
You actually need two service accounts. You need one that you set up yourself (can be whatever name you like and doesn't require any special permissions) and you also need the one for Cloud Scheduler itself.
Don't confuse the two. And use the one that you created when specifying the service account to generate the OAuth / OICD tokens.

GCP PubSub not honoring inherited permissions

Some of my service accounts are getting 403 (user not authorized) errors trying to publish/subscribe to PubSub. It appears it's not honoring "Inherited" permissions from Project level IAM.
I have verified the service accounts have IAM permissions to PubSub Subscriber & Viewer; and when I check the topic and subscriptions, they list the service accounts as type "Inherited". If I manually add the service account to the same permission from PubSub Console the UI lists it as "Mixed" and then it works.
Background - It was working before!
What's strange is this was working fine before. I accidentally deleted these same service accounts yesterday. I recreated them the same way, setup permissions the same way and it won't work. Also, the accounts that weren't deleted still work using "Inherited" permissions.
Some other things I've tried:
Created service account with different name from what was deleted - didn't work
Re-created topics/subs after creating service accounts and giving them project-wide permissions- didn't work
Long term I guess I'd prefer to control permissions per Topic/Sub; but I'm still baffled why this isn't working or what I've done wrong.
There currently seems to be a limitation with project-level permissions when a service account is deleted and recreated. The permissions for the newly created service account will not be propagated as expected.
If the service account is created with a different name, inherited permissions should work correctly. Note that permission propagation is not immediate and can have a delay. You may have to wait a few minutes to see the changes reflected.
For further assistance, you may need to contact Cloud Support so they can look into the specifics of your situation.