package iam import ( "fmt" "regexp" ) const svcAccountDomain = "iam.gserviceaccount.com" // WorkloadIdentitySvcAccount returns the email for the Workload Identity SA // for a given GCP Project + K8s identifiers. // https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#concepts func WorkloadIdentitySvcAccount(projectID, k8Namespace, k8SvcAct string) string { return fmt.Sprintf("%s.svc.id.goog[%s/%s]", projectID, k8Namespace, k8SvcAct) } // WorkloadIdentityMember returns the fully qualified member string for a // Workload Identity SA. func WorkloadIdentityMember(projectID, k8Namespace, K8SvcAct string) string { return SvcAccountMember(WorkloadIdentitySvcAccount(projectID, k8Namespace, K8SvcAct)) } // ComputeEngineSvcAccount returns the email for the GCP Compute Engine default // SA for a given GCP project number. This SA is also used on GKE nodes. // https://cloud.google.com/compute/docs/access/service-accounts#default_service_account func ComputeEngineSvcAccount(projectNum string) string { return fmt.Sprintf("%s-compute@developer.gserviceaccount.com", projectNum) } // ComputeEnginerSvcAccountMember returns the fully qualified member string // for the GCP Compute Engine default SA. func ComputeEngineSvcAccountMember(projectNum string) string { return SvcAccountMember(ComputeEngineSvcAccount(projectNum)) } // UserMember creates a valid GCP IAM user string for the provided emailid // requires _full_ emailid, see https://cloud.google.com/iam/docs/reference/rest/v1/Policy#Binding func UserMember(emailid string) string { return fmt.Sprintf("user:%s", emailid) } // SvcAccountMemmber returns the member string for a given service accounts // email func SvcAccountMember(email string) string { return fmt.Sprintf("serviceAccount:%s", email) } // SvcAccountEmail returns the email address for a standard user-created service // account name based on the project ID func SvcAccountEmail(name, projectID string) string { return fmt.Sprintf("%s@%s.%s", name, projectID, svcAccountDomain) } // StandardAccountMember creates a string representing a member of a GCP Policy // for a service account, see https://cloud.google.com/iam/docs/reference/rest/v1/Policy#Binding func StandardSvcAccountMember(name, projectID string) string { return SvcAccountMember(SvcAccountEmail(name, projectID)) } // LoggingSvcAccount returns the email for the GCP logging default // SA for a given GCP project number. func LoggingSvcAccount(projectNum string) string { return fmt.Sprintf("service-%s@gcp-sa-logging.iam.gserviceaccount.com", projectNum) } // LoggingServiceAccountMember creates a string representing a member of a GCP Policy // for a service account, see https://cloud.google.com/iam/docs/reference/rest/v1/Policy#Binding func LoggingServiceAccountMember(projectNum string) string { return SvcAccountMember(LoggingSvcAccount(projectNum)) } // reValidAccountID is compiled once at startup and used within the ValidAccountID function. var reValidAccountID = regexp.MustCompile(`^[a-z]([-]?[a-z0-9])+$`) // ValidAccountID checks an id string against a regex to determine if it is a valid service account resource name. // Resource names must adhere to the following pattern: // - starts with a letter // - has between 6 and 30 alphanumeric characters including dashes // - ends with a single alphanumeric character // // See the following document that calls out the restrictions: https://cloud.google.com/iam/docs/service-accounts-create func ValidAccountID(id string) bool { var validLength = len(id) >= 6 && len(id) <= 30 return validLength && reValidAccountID.MatchString(id) }