1 package iam 2 3 import ( 4 "fmt" 5 "regexp" 6 ) 7 8 const svcAccountDomain = "iam.gserviceaccount.com" 9 10 // WorkloadIdentitySvcAccount returns the email for the Workload Identity SA 11 // for a given GCP Project + K8s identifiers. 12 // https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#concepts 13 func WorkloadIdentitySvcAccount(projectID, k8Namespace, k8SvcAct string) string { 14 return fmt.Sprintf("%s.svc.id.goog[%s/%s]", projectID, k8Namespace, k8SvcAct) 15 } 16 17 // WorkloadIdentityMember returns the fully qualified member string for a 18 // Workload Identity SA. 19 func WorkloadIdentityMember(projectID, k8Namespace, K8SvcAct string) string { 20 return SvcAccountMember(WorkloadIdentitySvcAccount(projectID, k8Namespace, K8SvcAct)) 21 } 22 23 // ComputeEngineSvcAccount returns the email for the GCP Compute Engine default 24 // SA for a given GCP project number. This SA is also used on GKE nodes. 25 // https://cloud.google.com/compute/docs/access/service-accounts#default_service_account 26 func ComputeEngineSvcAccount(projectNum string) string { 27 return fmt.Sprintf("%s-compute@developer.gserviceaccount.com", projectNum) 28 } 29 30 // ComputeEnginerSvcAccountMember returns the fully qualified member string 31 // for the GCP Compute Engine default SA. 32 func ComputeEngineSvcAccountMember(projectNum string) string { 33 return SvcAccountMember(ComputeEngineSvcAccount(projectNum)) 34 } 35 36 // UserMember creates a valid GCP IAM user string for the provided emailid 37 // requires _full_ emailid, see https://cloud.google.com/iam/docs/reference/rest/v1/Policy#Binding 38 func UserMember(emailid string) string { 39 return fmt.Sprintf("user:%s", emailid) 40 } 41 42 // SvcAccountMemmber returns the member string for a given service accounts 43 // email 44 func SvcAccountMember(email string) string { 45 return fmt.Sprintf("serviceAccount:%s", email) 46 } 47 48 // SvcAccountEmail returns the email address for a standard user-created service 49 // account name based on the project ID 50 func SvcAccountEmail(name, projectID string) string { 51 return fmt.Sprintf("%s@%s.%s", name, projectID, svcAccountDomain) 52 } 53 54 // StandardAccountMember creates a string representing a member of a GCP Policy 55 // for a service account, see https://cloud.google.com/iam/docs/reference/rest/v1/Policy#Binding 56 func StandardSvcAccountMember(name, projectID string) string { 57 return SvcAccountMember(SvcAccountEmail(name, projectID)) 58 } 59 60 // LoggingSvcAccount returns the email for the GCP logging default 61 // SA for a given GCP project number. 62 func LoggingSvcAccount(projectNum string) string { 63 return fmt.Sprintf("service-%s@gcp-sa-logging.iam.gserviceaccount.com", projectNum) 64 } 65 66 // LoggingServiceAccountMember creates a string representing a member of a GCP Policy 67 // for a service account, see https://cloud.google.com/iam/docs/reference/rest/v1/Policy#Binding 68 func LoggingServiceAccountMember(projectNum string) string { 69 return SvcAccountMember(LoggingSvcAccount(projectNum)) 70 } 71 72 // reValidAccountID is compiled once at startup and used within the ValidAccountID function. 73 var reValidAccountID = regexp.MustCompile(`^[a-z]([-]?[a-z0-9])+$`) 74 75 // ValidAccountID checks an id string against a regex to determine if it is a valid service account resource name. 76 // Resource names must adhere to the following pattern: 77 // - starts with a letter 78 // - has between 6 and 30 alphanumeric characters including dashes 79 // - ends with a single alphanumeric character 80 // 81 // See the following document that calls out the restrictions: https://cloud.google.com/iam/docs/service-accounts-create 82 func ValidAccountID(id string) bool { 83 var validLength = len(id) >= 6 && len(id) <= 30 84 return validLength && reValidAccountID.MatchString(id) 85 } 86