Permissions in Google Cloud Platform¶
Identity & Access Mangement (IAM) lets you create and manage permissions for Google Cloud resources on the Google Cloud Platform (GCP).
Info
Please read through the Google Cloud IAM documentation for a more thorough introduction to IAM and related concepts.
Most services (e.g. PostgreSQL, Cloud Storage / Buckets, BigQuery) offered by NAIS on GCP will automatically be configured with any needed permissions that allows your application to access them.
In cases where you wish to use other services in the Google Cloud Platform not officially supported by NAIS, you will also have to set up permissions that allows your application to access these resources.
Concepts¶
Permissions¶
See https://cloud.google.com/iam/docs/overview#permissions.
Roles¶
See https://cloud.google.com/iam/docs/overview#roles.
See also Google Cloud Predefined Roles for a list of predefined roles.
Policy Granularity¶
Google Cloud resources are organized hierarchically. A policy that grants a principal (a user or a service account) any permissions to a resource will thus also apply to any children of said resource. This allows for fine-grained access control.
For example, you may grant the roles/pubsub.subscriber
role for your application at the project-level. This means that
the application will have the role for any PubSub subscription for the entire project. If you instead grant the same
role at the subscription-level, the application would only have access to a specific PubSub subscription.
See https://cloud.google.com/iam/docs/overview#resource-hierarchy.
Service Accounts¶
Applications running on Kubernetes (which is the runtime platform at the core of NAIS) each have an associated Kubernetes Service Account (KSA). This account provides an identity for the individual applications running on the platform.
To access the various Google Cloud resources, a Google Service Account (GSA) is required. For simplicity's sake, NAIS automatically provisions Google Service Accounts for each application that is deployed to the GCP clusters. The Google Service Account is uniquely identified by its email address:
You can find this email for your application's GSA by querying the clusters. Ensure that you have set up access to the Kubernetes clusters first, then run the following command:
kubectl get sa <app> \
-ojsonpath="{.metadata.annotations.\iam\.gke\.io/gcp-service-account}" \
-n <namespace>
Authentication¶
In order to authenticate using the identity of the Google Service Account, we need a set of credentials. The documentation on Google Cloud Platform mention several best practices for managing such credentials. One of these practices is to use workload identity.
Workload identity works by essentially creating a mapping between a Kubernetes Service Account and a Google Service Account. In other words, your application can authenticate itself with the Kubernetes Service Account credentials, and access Google Cloud APIs with the identity of the Google Service Account.
If your application uses the official Google Client Libraries, the library will automatically discover and handle authentication.
For local development, you can acquire credentials for your own user account by using Application Default Credentials. Your application will then automatically discover and use these when running locally. Ensure that your user has the required permissions or roles to access the Google Cloud resources and APIs used by your application.
Granting permissions¶
There are multiple ways of granting your application access to Google Cloud resources.
Declaratively¶
The NAIS application manifest allows for basic configuration to grant roles to your application roles. This can either apply for a specific resource or for the entire project. To do so, you need the following information:
Field | Description | Example value |
---|---|---|
Kind | The Config Connector Resource Name. See the list of supported resources. | KMSCryptoKey |
APIVersion | The apiVersion associated with the above kind . See the list of resources, find the matching kind and see the sample YAMLs to find the correct apiVersion value. |
kms.cnrm.cloud.google.com/v1beta1 (source) |
Role | See predefined roles for a list of available predefined roles for each resource. | cloudkms.cryptoKeyEncrypterDecrypter |
Name | The resource name or reference in Google Cloud. Not needed for project-wide access. See the table for external reference formats. | projects/<project-ID>/locations/<location>/keyRings/<key-ring-ID>/cryptoKeys/<key-name> |
See also the resource reference table below for some common combinations.
For example:
spec:
gcp:
permissions:
- resource:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
kind: Project
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
The above example grants your application the role roles/cloudkms.cryptoKeyEncrypterDecrypter
at the project level. This means
that your application will have this role for any Cloud KMS resource in your project.
Note that the name
field is omitted as it is automatically inferred.
If you only want your application to be able to access a specific key in Cloud KMS, the example would look like this:
spec:
gcp:
permissions:
- resource:
apiVersion: kms.cnrm.cloud.google.com/v1beta1
kind: KMSCryptoKey
name: locations/europe-north1/keyRings/<some-key-ring>/cryptoKeys/<some-key>
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
Note that you can omit the project/<project ID>/
-prefix from the name
value, as shown in the example. The prefix
is automatically inferred by the NAIS platform.
Resource Reference¶
The table below summarizes the combinations of apiVersion
, kind
and name
formats for a few of
the most commonly used resources:
Kind | APIVersion | Name |
---|---|---|
Project |
resourcemanager.cnrm.cloud.google.com/v1beta1 |
<empty> |
KMSCryptoKey |
kms.cnrm.cloud.google.com/v1beta1 |
locations/{{location}}/keyRings/{{key_ring_id}}/cryptoKeys/{{key_name}} |
KMSKeyRing |
kms.cnrm.cloud.google.com/v1beta1 |
locations/{{location}}/keyRings/{{key_ring_id}} |
PubSubSubscription |
pubsub.cnrm.cloud.google.com/v1beta1 |
subscriptions/{{subscription_name}} |
PubSubTopic |
pubsub.cnrm.cloud.google.com/v1beta1 |
topics/{{topic_name}} |
SecretManagerSecret |
secretmanager.cnrm.cloud.google.com/v1beta1 |
secrets/{{secret_id}} |
Debugging¶
List the IAMPolicyMembers
created for your application and check for any errors:
NAME AGE READY STATUS STATUS AGE
my-app-17135ea6bddbfb87-0c3df6d4 47h True UpToDate 47h
my-app-2c73ffe043d5bdfb-3afabf2b 46h False DependencyNotReady 46h
my-app-5807c739790a971a-65560940 4d12h True UpToDate 4d12h
Inspect the failing IAMPolicyMember
resource by describing the resource and looking for the events:
Name: my-app-2c73ffe043d5bdfb-3afabf2b
Kind: IAMPolicyMember
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning DependencyNotReady 2m27s (x2911 over 4d) iampolicymember-controller reference StorageBucket my-namespace/my-app-bucket is not ready
Cloud Console¶
See the Google Cloud documentation for granting access to either projects or lower level resources.
Created: 2022-07-07