feat: add service account impersonation support

The impersonated_service_account type in the JSON configuration file is taken into account. source_credentials field in the JSON is now supported.

Fixes #515
This commit is contained in:
guillaume blaquiere 2021-08-23 10:43:18 +02:00 committed by Guillaume Blaquiere
parent 6b3c2da341
commit cb87a576ab
1 changed files with 24 additions and 3 deletions

View File

@ -95,6 +95,7 @@ const (
serviceAccountKey = "service_account" serviceAccountKey = "service_account"
userCredentialsKey = "authorized_user" userCredentialsKey = "authorized_user"
externalAccountKey = "external_account" externalAccountKey = "external_account"
impersonatedServiceAccount = "impersonated_service_account"
) )
// credentialsFile is the unmarshalled representation of a credentials file. // credentialsFile is the unmarshalled representation of a credentials file.
@ -124,6 +125,9 @@ type credentialsFile struct {
CredentialSource externalaccount.CredentialSource `json:"credential_source"` CredentialSource externalaccount.CredentialSource `json:"credential_source"`
QuotaProjectID string `json:"quota_project_id"` QuotaProjectID string `json:"quota_project_id"`
WorkforcePoolUserProject string `json:"workforce_pool_user_project"` WorkforcePoolUserProject string `json:"workforce_pool_user_project"`
// Service account impersonation
SourceCredentials *credentialsFile `json:"source_credentials"`
} }
func (f *credentialsFile) jwtConfig(scopes []string, subject string) *jwt.Config { func (f *credentialsFile) jwtConfig(scopes []string, subject string) *jwt.Config {
@ -180,6 +184,23 @@ func (f *credentialsFile) tokenSource(ctx context.Context, params CredentialsPar
WorkforcePoolUserProject: f.WorkforcePoolUserProject, WorkforcePoolUserProject: f.WorkforcePoolUserProject,
} }
return cfg.TokenSource(ctx) return cfg.TokenSource(ctx)
case impersonatedServiceAccount:
if f.SourceCredentials == nil {
return nil, errors.New("missing 'source_credentials' field in credentials")
}
sourceToken, err := f.SourceCredentials.tokenSource(ctx, params)
if err != nil {
return nil, err
}
imp := externalaccount.ImpersonateTokenSource{
Ctx: ctx,
Url: f.ServiceAccountImpersonationURL,
Scopes: params.Scopes,
Ts: oauth2.ReuseTokenSource(nil, sourceToken),
// Delegates?? -> I don't know how to manage and how to use them here
}
return oauth2.ReuseTokenSource(nil, imp), nil
case "": case "":
return nil, errors.New("missing 'type' field in credentials") return nil, errors.New("missing 'type' field in credentials")
default: default: