-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cloud/gcp: add assume role for GCS and GCP KMS #80417
Conversation
46ae65c
to
8a99af4
Compare
e274c6e
to
23f89f6
Compare
@adityamaru do you mind reviewing this PR? |
on it, sorry for the delay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits and questions. Can we edit the Release Note to maybe add an example of what form a URL with ASSUME
and TARGET
would look like?
pkg/roachpb/api.proto
Outdated
@@ -1398,6 +1398,8 @@ message ExternalStorage { | |||
string billing_project = 4; | |||
|
|||
string credentials = 5; | |||
|
|||
string target = 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment describing what target
is? I think it's a generic enough word that it might help to provide some gcs specific context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to service account, which should be more self descriptive.
pkg/cloud/gcp/gcs_kms.go
Outdated
@@ -68,11 +70,21 @@ func MakeGCSKMS(uri string, env cloud.KMSEnv) (cloud.KMS, error) { | |||
|
|||
// Client options to authenticate and start a GCS KMS session. | |||
// Currently only accepting json of service account. | |||
var credentialsOpt []option.ClientOption | |||
var clientOpts []option.ClientOption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there any reason to pull this out? It seems like its logic that is specific to only cloud.AuthParamSpecified
so should we move it back inside the case stmt for readability or am I missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. Reverted this section back to what it was. I originally had this code reused for specified credentials for the assume AUTH but that code turned out to be slightly different in the end.
pkg/cloud/gcp/gcs_storage.go
Outdated
@@ -43,6 +45,9 @@ const ( | |||
// CredentialsParam is the query parameter for the base64-encoded contents of | |||
// the Google Application Credentials JSON file. | |||
CredentialsParam = "CREDENTIALS" | |||
// TargetPrincipalParam is the target principal to impersonate. The target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just for my edification what is a principal? Do you think it is worth spelling that out here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change this to SERVICE_ACCOUNT actually (and also in other places target
is used). I originally wanted to use the same params as the API in the impersonate
package but it's probably more clear to just call everything "service account"
pkg/cloud/gcp/gcs_storage.go
Outdated
@@ -116,26 +122,38 @@ func makeGCSStorage( | |||
|
|||
switch conf.Auth { | |||
case cloud.AuthParamImplicit: | |||
// Do nothing; use implicit params: | |||
// Use implicit params to access storage or impersonate target: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does AuthParamImplicit interact with impersonating a target? I'm probably missing something here but this case doesn't have fallthrough
so implicit is doing what it used to do i.e. not setup any options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, removed this comment change. There's no interaction with implicit auth and impersonate.
pkg/cloud/gcp/gcs_storage.go
Outdated
|
||
assumeOpt, err := createImpersonateCredentials(ctx, conf.Target, []string{scope}, conf.Credentials) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed to assume %s", conf.Target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will Target
have sensitive information?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm you're right. I suppose that there could be information revealed about what the service account does from its email address. I've removed it from the logging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed comments. Also modified the release note to add some example URIs with this change.
pkg/cloud/gcp/gcs_kms.go
Outdated
@@ -68,11 +70,21 @@ func MakeGCSKMS(uri string, env cloud.KMSEnv) (cloud.KMS, error) { | |||
|
|||
// Client options to authenticate and start a GCS KMS session. | |||
// Currently only accepting json of service account. | |||
var credentialsOpt []option.ClientOption | |||
var clientOpts []option.ClientOption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. Reverted this section back to what it was. I originally had this code reused for specified credentials for the assume AUTH but that code turned out to be slightly different in the end.
pkg/cloud/gcp/gcs_storage.go
Outdated
@@ -43,6 +45,9 @@ const ( | |||
// CredentialsParam is the query parameter for the base64-encoded contents of | |||
// the Google Application Credentials JSON file. | |||
CredentialsParam = "CREDENTIALS" | |||
// TargetPrincipalParam is the target principal to impersonate. The target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change this to SERVICE_ACCOUNT actually (and also in other places target
is used). I originally wanted to use the same params as the API in the impersonate
package but it's probably more clear to just call everything "service account"
pkg/cloud/gcp/gcs_storage.go
Outdated
@@ -116,26 +122,38 @@ func makeGCSStorage( | |||
|
|||
switch conf.Auth { | |||
case cloud.AuthParamImplicit: | |||
// Do nothing; use implicit params: | |||
// Use implicit params to access storage or impersonate target: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, removed this comment change. There's no interaction with implicit auth and impersonate.
pkg/cloud/gcp/gcs_storage.go
Outdated
|
||
assumeOpt, err := createImpersonateCredentials(ctx, conf.Target, []string{scope}, conf.Credentials) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed to assume %s", conf.Target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm you're right. I suppose that there could be information revealed about what the service account does from its email address. I've removed it from the logging.
pkg/roachpb/api.proto
Outdated
@@ -1398,6 +1398,8 @@ message ExternalStorage { | |||
string billing_project = 4; | |||
|
|||
string credentials = 5; | |||
|
|||
string target = 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to service account, which should be more self descriptive.
pkg/cloud/gcp/gcs_storage.go
Outdated
// ServiceAccountParam is the email of the service account to impersonate. | ||
// This service account should have the necessary access to the relevant cloud | ||
// services. | ||
ServiceAccountParam = "SERVICE_ACCOUNT" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I definitely think ServiceAccount is clearer than target but does this now give the impression that we are passing the service account that will be used to access cloud services? I guess in a way we are but should we be more explicit and call it ASSUMED_SERVICE_ACCOUNT
or something? Might also be worth asking a few more folks for a bikeshed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, now we are using the param ASSUME_ROLE
and not using an additional auth method
pkg/roachpb/api.proto
Outdated
@@ -1424,6 +1424,8 @@ message ExternalStorage { | |||
string billing_project = 4; | |||
|
|||
string credentials = 5; | |||
|
|||
string service_account = 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
depending on how we address the comment on the URI param name we should change this accordingly. A comment might still be nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added comment
go.mod
Outdated
@@ -5,7 +5,7 @@ go 1.17 | |||
require ( | |||
cloud.google.com/go/kms v1.1.0 | |||
cloud.google.com/go/pubsub v1.16.0 | |||
cloud.google.com/go/storage v1.21.0 | |||
cloud.google.com/go/storage v1.22.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just checking what motivated this bump?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer bumped with the separate vendor PR
3f4b9fd
to
61c1cc4
Compare
@adityamaru this should be ready FAL |
credentialsOpt = append(credentialsOpt, authOption) | ||
} | ||
|
||
opts := []option.ClientOption{option.WithScopes(scope)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we add a quick comment mentioning that once we have resolved AUTH as implicit or specified we check if we need to use these creds to assume a role.
pkg/cmd/roachtest/tests/backup.go
Outdated
m.Go(func(ctx context.Context) error { | ||
t.Status(`running backup`) | ||
c.Run(ctx, c.Node(1), fmt.Sprintf( | ||
"./cockroach sql --insecure -e \"BACKUP bank.bank TO '%s' WITH KMS='%s'\"", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we use the BACKUP INTO
syntax? We want to get rid of TO
soonish so we'll have to cleanup all roachtests eventually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it useful to RESTORE from the backup and check if the table has expected rows as well? It'll be a more complete test imo, wdyt?
nit: We should update PR description with updated commit message |
Add service account impersonation for GCS and GCP KMS. This is the assume role equivalent for GCP that allows the service account from implicit or specified credentials to obtain temporary credentials for another service account. Release note (enterprise change): Storage and KMS URIs for GCP in Backup and restore now accept an "ASSUME_ROLE" parameter, which informs the current service account authenticated by either implicit or specified credentials to obtain temporary credentials for the service account specified by the ASSUME_ROLE parameter in order to access the resource specified by the URI. Below are examples of URIs with "ASSUME_ROLE" parameter: ``` GCS: gs://<bucket>/<key>?AUTH=specified&ASSUME_ROLE=<service_account>@<project>.iam.gserviceaccount.com&CREDENTIALS=<credentials> KMS GCP: gs:///<key_resource_name>?AUTH=implicit&ASSUME_ROLE=<service_account>@<project>.iam.gserviceaccount.com ```
bors r+ |
Build succeeded: |
Add service account impersonation for GCS and GCP KMS. This is the assume role
equivalent for GCP that allows the service account from implicit or specified
credentials to obtain temporary credentials for another service account.
Release note (enterprise change): Storage and KMS URIs for GCP in Backup and
restore now accept an "ASSUME_ROLE" parameter, which informs the current
service account authenticated by either implicit or specified credentials to
obtain temporary credentials for the service account specified by the
ASSUME_ROLE parameter in order to access the resource specified by the URI.
Below are examples of URIs with "ASSUME_ROLE" parameter: