Package downscope implements the ability to downscope, or restrict, the Identity and Access Management permissions that a short-lived Token can use. Please note that only Google Cloud Storage supports this feature. For complete documentation, see https://cloud.google.com/iam/docs/downscoping-short-lived-credentials
To downscope permissions of a source credential, you need to define a Credential Access Boundary. Said Boundary specifies which resources the newly created credential can access, an upper bound on the permissions it has over those resources, and optionally attribute-based conditional access to the aforementioned resources. For more information on IAM Conditions, see https://cloud.google.com/iam/docs/conditions-overview.
This functionality can be used to provide a third party with limited access to and permissions on resources held by the owner of the root credential or internally in conjunction with the principle of least privilege to ensure that internal services only hold the minimum necessary privileges for their function.
For example, a token broker can be set up on a server in a private network. Various workloads (token consumers) in the same network will send authenticated requests to that broker for downscoped tokens to access or modify specific google cloud storage buckets. See the NewCredentials example for an example of how a token broker would use this package.
The broker will use the functionality in this package to generate a downscoped token with the requested configuration, and then pass it back to the token consumer. These downscoped access tokens can then be used to access Google Cloud resources.
Functions
func NewCredentials
func NewCredentials(opts *Options) (*auth.Credentials, error)
NewCredentials returns a [cloud.google.com/go/auth.Credentials] that is more restrictive than [Options.Credentials] provided. The new credentials will delegate to the base credentials for all non-token activity.
Example
package main
import (
"context"
"fmt"
"cloud.google.com/go/auth/credentials"
"cloud.google.com/go/auth/credentials/downscope"
)
func main() {
// This shows how to generate a downscoped token. This code would be run on
// the token broker, which holds the root token used to generate the
// downscoped token.
ctx := context.Background()
// Initializes an accessBoundary with one Rule which restricts the
// downscoped token to only be able to access the bucket "foo" and only
// grants it the permission "storage.objectViewer".
accessBoundary := []downscope.AccessBoundaryRule{
{
AvailableResource: "//storage.googleapis.com/projects/_/buckets/foo",
AvailablePermissions: []string{"inRole:roles/storage.objectViewer"},
},
}
// This Source can be initialized in multiple ways; the following example uses
// Application Default Credentials.
baseProvider, err := credentials.DetectDefault(&credentials.DetectOptions{
Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"},
})
creds, err := downscope.NewCredentials(&downscope.Options{Credentials: baseProvider, Rules: accessBoundary})
if err != nil {
fmt.Printf("failed to generate downscoped token provider: %v", err)
return
}
tok, err := creds.Token(ctx)
if err != nil {
fmt.Printf("failed to generate token: %v", err)
return
}
_ = tok
// You can now pass tok to a token consumer however you wish, such as exposing
// a REST API and sending it over HTTP.
// You can instead use the token held in tp to make
// Google Cloud Storage calls, as follows:
// storageClient, err := storage.NewClient(ctx, option.WithTokenProvider(tp))
}
AccessBoundaryRule
type AccessBoundaryRule struct {
// AvailableResource is the full resource name of the Cloud Storage bucket
// that the rule applies to. Use the format
// //storage.googleapis.com/projects/_/buckets/bucket-name.
AvailableResource string `json:"availableResource"`
// AvailablePermissions is a list that defines the upper bound on the available permissions
// for the resource. Each value is the identifier for an IAM predefined role or custom role,
// with the prefix inRole:. For example: inRole:roles/storage.objectViewer.
// Only the permissions in these roles will be available.
AvailablePermissions []string `json:"availablePermissions"`
// An Condition restricts the availability of permissions
// to specific Cloud Storage objects. Optional.
//
// A Condition can be used to make permissions available for specific objects,
// rather than all objects in a Cloud Storage bucket.
Condition *AvailabilityCondition `json:"availabilityCondition,omitempty"`
}
An AccessBoundaryRule Sets the permissions (and optionally conditions) that the new token has on given resource.
AvailabilityCondition
type AvailabilityCondition struct {
// An Expression specifies the Cloud Storage objects where
// permissions are available. For further documentation, see
// https://cloud.google.com/iam/docs/conditions-overview. Required.
Expression string `json:"expression"`
// Title is short string that identifies the purpose of the condition. Optional.
Title string `json:"title,omitempty"`
// Description details about the purpose of the condition. Optional.
Description string `json:"description,omitempty"`
}
An AvailabilityCondition restricts access to a given Resource.
Options
type Options struct {
// Credentials is the [cloud.google.com/go/auth.Credentials] used to
// create the downscoped credentials. Required.
Credentials *auth.Credentials
// Rules defines the accesses held by the new downscoped credentials. One or
// more AccessBoundaryRules are required to define permissions for the new
// downscoped credentials. Each one defines an access (or set of accesses)
//that the new credentials has to a given resource. There can be a maximum
// of 10 AccessBoundaryRules. Required.
Rules []AccessBoundaryRule
// Client configures the underlying client used to make network requests
// when fetching tokens. Optional.
Client *http.Client
// UniverseDomain is the default service domain for a given Cloud universe.
// The default value is "googleapis.com". Optional.
UniverseDomain string
}
Options for configuring [NewCredentials].