forked from GoogleCloudPlatform/nodejs-docs-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdownscoping.js
More file actions
174 lines (160 loc) · 6.07 KB
/
Copy pathdownscoping.js
File metadata and controls
174 lines (160 loc) · 6.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Copyright 2021, Google, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
'use strict';
const downscopingWithCredentialAccessBoundary = async ({
bucketName,
objectName,
}) => {
// [START auth_downscoping_token_broker]
// Imports the Google Auth libraries.
const {GoogleAuth, DownscopedClient} = require('google-auth-library');
/**
* Simulates token broker generating downscoped tokens for specified bucket.
*
* @param bucketName The name of the Cloud Storage bucket.
* @param objectPrefix The prefix string of the object name. This is used
* to ensure access is restricted to only objects starting with this
* prefix string.
*/
async function getTokenFromBroker(bucketName, objectPrefix) {
const googleAuth = new GoogleAuth({
scopes: 'https://www.googleapis.com/auth/cloud-platform',
});
// [START auth_downscoping_rules]
// Define the Credential Access Boundary object.
const cab = {
// Define the access boundary.
accessBoundary: {
// Define the single access boundary rule.
accessBoundaryRules: [
{
availableResource: `//storage.googleapis.com/projects/_/buckets/${bucketName}`,
// Downscoped credentials will have readonly access to the resource.
availablePermissions: ['inRole:roles/storage.objectViewer'],
// Only objects starting with the specified prefix string in the object name
// will be allowed read access.
availabilityCondition: {
expression:
"resource.name.startsWith('projects/_/buckets/" +
`${bucketName}/objects/${objectPrefix}')`,
},
},
],
},
};
// [END auth_downscoping_rules]
// [START auth_downscoping_initialize_downscoped_cred]
// Obtain an authenticated client via ADC.
const client = await googleAuth.getClient();
// Use the client to create a DownscopedClient.
const cabClient = new DownscopedClient(client, cab);
// Refresh the tokens.
const refreshedAccessToken = await cabClient.getAccessToken();
// [END auth_downscoping_initialize_downscoped_cred]
// This will need to be passed to the token consumer.
return refreshedAccessToken;
}
// [END auth_downscoping_token_broker]
// [START auth_downscoping_token_consumer]
// Imports the Google Auth and Google Cloud libraries.
const {OAuth2Client} = require('google-auth-library');
const {Storage} = require('@google-cloud/storage');
/**
* Simulates token consumer generating calling GCS APIs using generated
* downscoped tokens for specified bucket.
*
* @param bucketName The name of the Cloud Storage bucket.
* @param objectName The name of the object in the Cloud Storage bucket
* to read.
*/
async function tokenConsumer(bucketName, objectName) {
// Create the OAuth credentials (the consumer).
const oauth2Client = new OAuth2Client();
// We are defining a refresh handler instead of a one-time access
// token/expiry pair.
// This will allow the consumer to obtain new downscoped tokens on
// demand every time a token is expired, without any additional code
// changes.
oauth2Client.refreshHandler = async () => {
// The common pattern of usage is to have a token broker pass the
// downscoped short-lived access tokens to a token consumer via some
// secure authenticated channel. For illustration purposes, we are
// generating the downscoped token locally. We want to test the ability
// to limit access to objects with a certain prefix string in the
// resource bucket. objectName.substring(0, 3) is the prefix here. This
// field is not required if access to all bucket resources are allowed.
// If access to limited resources in the bucket is needed, this mechanism
// can be used.
const refreshedAccessToken = await getTokenFromBroker(
bucketName,
objectName.substring(0, 3)
);
return {
access_token: refreshedAccessToken.token,
expiry_date: refreshedAccessToken.expirationTime,
};
};
const storageOptions = {
projectId: process.env.GOOGLE_CLOUD_PROJECT,
authClient: oauth2Client,
};
const storage = new Storage(storageOptions);
const downloadFile = await storage
.bucket(bucketName)
.file(objectName)
.download();
console.log(downloadFile.toString('utf8'));
}
// [END auth_downscoping_token_consumer]
try {
tokenConsumer(bucketName, objectName);
} catch (error) {
console.log(error);
}
};
// TODO(developer): Replace these variables before running the sample.
// The Cloud Storage bucket name.
const bucketName = 'your-gcs-bucket-name';
// The Cloud Storage object name that resides in the specified bucket.
const objectName = 'your-gcs-object-name';
const cli = require('yargs')
.demand(2)
.command(
'auth-downscoping-with-credential-access-boundary',
'Loads Downscoped Credentials.',
{
bucketName: {
alias: 'b',
default: bucketName,
},
objectName: {
alias: 'o',
default: objectName,
},
},
downscopingWithCredentialAccessBoundary
)
.example(
'node $0 auth-downscoping-with-credential-access-boundary -b your-gcs-bucket-name -o your-gcs-object-name',
'Loads Downscoped Credentials.'
)
.wrap(120)
.recommendCommands()
.epilogue(
'For more information, see https://cloud.google.com/iam/docs/downscoping-short-lived-credentials'
)
.help()
.strict();
if (module === require.main) {
cli.parse(process.argv.slice(2));
}