Last active
January 30, 2025 01:24
-
-
Save salrashid123/a7e8c9043d27cb0478b36cf0303a2f20 to your computer and use it in GitHub Desktop.
Access GCP and workspace APIs using GCP Workload Identity Federation usign Domain Delegation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"context" | |
"cloud.google.com/go/storage" | |
admin "google.golang.org/api/admin/directory/v1" | |
driveactivity "google.golang.org/api/driveactivity/v2" | |
"google.golang.org/api/impersonate" | |
"google.golang.org/api/iterator" | |
"google.golang.org/api/option" | |
) | |
/* | |
Access GCP and workspace APIs using GCP Workload Identity Federation | |
see | |
* https://blog.salrashid.dev/articles/2021/impersonation_and_domain_delegation/ | |
* https://blog.salrashid.dev/articles/2021/understanding_workload_identity_federation/ | |
* https://pkg.go.dev/google.golang.org/api/impersonate#example-CredentialsTokenSource-AdminUser | |
using fake oidc server here: | |
https://gist.github.com/salrashid123/677866e42cf2785fe885ae9d6130fc21 | |
create an oidc token and set | |
$ cat sts-creds.json | |
{ | |
"type": "external_account", | |
"audience": "//iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/fake-oidc-pool-1/providers/fake-oidc-provider-1", | |
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt", | |
"token_url": "https://sts.googleapis.com/v1/token", | |
"credential_source": { | |
"file": "/tmp/oidccred.txt" | |
} | |
} | |
grant the candidate service account 'self-impersonation' permissions | |
$ gcloud iam service-accounts describe tpm-sa@$PROJECT_ID.iam.gserviceaccount.com | |
email: tpm-sa@$PROJECT_ID.iam.gserviceaccount.com | |
etag: MDEwMjE5MjA= | |
name: projects/$PROJECT_ID/serviceAccounts/tpm-sa@$PROJECT_ID.iam.gserviceaccount.com | |
oauth2ClientId: '100890260483227123113' | |
projectId: $PROJECT_ID | |
uniqueId: '100890260483227123113' | |
gcloud iam service-accounts \ | |
add-iam-policy-binding tpm-sa@$PROJECT_ID.iam.gserviceaccount.com \ | |
--member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/fake-oidc-pool-1/subject/[email protected] \ | |
--role=roles/iam.serviceAccountTokenCreator | |
grant service account domain delegation rights to scopes | |
admin.AdminDirectoryUserReadonlyScope, driveactivity.DriveActivityReadonlyScope, "https://www.googleapis.com/auth/cloud-platform" | |
as described in: https://blog.salrashid.dev/articles/2021/impersonation_and_domain_delegation/ | |
finally | |
export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/sts-creds.json | |
go run main.go | |
*/ | |
func main() { | |
ctx := context.Background() | |
// c1_adc := fmt.Sprintf(`{ | |
// "type": "external_account", | |
// "audience": "%s", | |
// "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", | |
// "token_url": "https://sts.googleapis.com/v1/token", | |
// "credential_source": { | |
// "file": "%s" | |
// } | |
// }`, "//iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/fake-oidc-pool-1/providers/fake-oidc-provider-1", "/tmp/oidccred.txt") | |
// ts, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{ | |
// TargetPrincipal: "tpm-sa@$PROJECT_ID.gserviceaccount.com", | |
// Scopes: []string{admin.AdminDirectoryUserReadonlyScope, driveactivity.DriveActivityReadonlyScope, "https://www.googleapis.com/auth/cloud-platform"}, | |
// Subject: "[email protected]", | |
// }, option.WithCredentialsJSON([]byte(c1_adc))) | |
ts, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{ | |
TargetPrincipal: "tpm-sa@$PROJECT_ID.iam.gserviceaccount.com", | |
Scopes: []string{admin.AdminDirectoryUserReadonlyScope, driveactivity.DriveActivityReadonlyScope, "https://www.googleapis.com/auth/cloud-platform"}, | |
Subject: "[email protected]", | |
}) | |
if err != nil { | |
log.Fatal(err) | |
} | |
storageClient, err := storage.NewClient(ctx, option.WithTokenSource(ts)) | |
if err != nil { | |
log.Fatalf("%v", err) | |
} | |
bucketName := "some-bucket" | |
it := storageClient.Bucket(bucketName).Objects(ctx, nil) | |
for { | |
attrs, err := it.Next() | |
if err == iterator.Done { | |
break | |
} | |
if err != nil { | |
log.Fatal(err) | |
} | |
log.Println(attrs.Name) | |
} | |
adminservice, err := admin.NewService(ctx, option.WithTokenSource(ts)) | |
if err != nil { | |
log.Fatal(err) | |
} | |
srv := admin.NewUsersService(adminservice) | |
// gcloud organizations list | |
usersReport, err := srv.List().Customer("your_customer_id").MaxResults(10).OrderBy("email").Do() | |
if err != nil { | |
log.Fatal(err) | |
} | |
if len(usersReport.Users) == 0 { | |
fmt.Print("No users found.\n") | |
} else { | |
fmt.Print("Users:\n") | |
for _, u := range usersReport.Users { | |
fmt.Printf("%s (%s)\n", u.PrimaryEmail, u.Name.FullName) | |
} | |
} | |
dsrv, err := driveactivity.NewService(ctx, option.WithTokenSource(ts)) | |
if err != nil { | |
log.Fatalf("Unable to retrieve driveactivity Client %v", err) | |
} | |
q := driveactivity.QueryDriveActivityRequest{PageSize: 10} | |
r, err := dsrv.Activity.Query(&q).Do() | |
if err != nil { | |
log.Fatalf("Unable to retrieve list of activities. %v", err) | |
} | |
fmt.Println("Recent Activity:") | |
if len(r.Activities) > 0 { | |
for _, a := range r.Activities { | |
for _, i := range a.Actors { | |
log.Printf("%s, \n", i.User.KnownUser.PersonName) | |
} | |
} | |
} else { | |
fmt.Print("No activity.") | |
} | |
} |
Author
salrashid123
commented
Oct 13, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment