-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Add service-to-service Node.js sample #1704
Changes from all commits
9d64ae1
64ab35f
00451bf
86b0635
5132e26
a176376
70ce8f7
5975b57
8e9ef37
42aa279
b53d157
0b6311a
c46ca0c
30dc7d0
0279f2a
a929c05
b3d410f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Format: //devtools/kokoro/config/proto/build.proto | ||
|
||
# Set the folder in which the tests are run | ||
env_vars: { | ||
key: "PROJECT" | ||
value: "run/authentication" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright 2020 Google LLC | ||
// | ||
// 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 | ||
// | ||
// https://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. | ||
|
||
const requestServiceToken = async (receivingServiceURL = 'https://SERVICE_NAME-HASH-run.app') => { | ||
// [START run_service_to_service_auth] | ||
kelsk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const gcpMetadata = require('gcp-metadata'); | ||
const got = require('got'); | ||
|
||
// TODO(developer): Add the URL of your receiving service | ||
// const receivingServiceURL = 'https://SERVICE_NAME-HASH-run.app' | ||
|
||
try { | ||
// Set up the metadata server request URL | ||
const metadataServerTokenPath = `service-accounts/default/identity?audience=${receivingServiceURL}`; | ||
|
||
// Fetch the token and then provide it in the request to the receiving service | ||
const token = await gcpMetadata.instance(metadataServerTokenPath); | ||
const serviceRequestOptions = { | ||
headers: { | ||
'Authorization': 'bearer ' + token | ||
} | ||
}; | ||
const serviceResponse = await got(receivingServiceURL, serviceRequestOptions); | ||
return serviceResponse; | ||
} catch (error) { | ||
console.log('Metadata server could not respond to query ', error); | ||
return error; | ||
}; | ||
|
||
// [END run_service_to_service_auth] | ||
|
||
}; | ||
requestServiceToken(...process.argv.slice(2)); | ||
|
||
module.exports = requestServiceToken; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
kelsk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"name": "nodejs-docs-samples-run-auth", | ||
"description": "Cloud Run service-to-service authentication", | ||
"version": "0.0.1", | ||
"private": true, | ||
"license": "Apache-2.0", | ||
"author": "Google LLC", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" | ||
}, | ||
"engines": { | ||
"node": ">= 10.0.0" | ||
}, | ||
"main": "auth.js", | ||
"scripts": { | ||
"start": "node auth.js", | ||
"test": "mocha test/*.test.js" | ||
}, | ||
"dependencies": { | ||
"express": "^4.16.4", | ||
kelsk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"gcp-metadata": "^4.0.0", | ||
"got": "^10.7.0" | ||
}, | ||
"devDependencies": { | ||
"mocha": "^7.0.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright 2020 Google LLC | ||
// | ||
// 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 | ||
// | ||
// https://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. | ||
|
||
const assert = require('assert'); | ||
const requestServiceToken = require('../auth.js'); | ||
|
||
let res; | ||
|
||
describe('requestServiceToken tests', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need some deeper test coverage: can we parse out the auth token and at least do basic validation that it's a proper JWT? |
||
before(async function () { | ||
this.timeout(3000); | ||
res = await requestServiceToken(''); | ||
}); | ||
|
||
it('should return an error if given invalid Receiving Service URL', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to have a test that passes. When running on kokoro a request to the metadata server should succeed. You could write a test that looks for the env var 'GCLOUD_PROJECT' but make a comment that it must be unset locally. |
||
assert.strictEqual(typeof res, 'object'); | ||
assert.strictEqual(res.code, 'EHOSTDOWN'); | ||
}); | ||
}); |
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.
Not sure I follow why this function exists? If we're running in an environment that can mint a token, let's write an integration test that mints the token. We can split the request function to something that returns the token from metadata so it can be tested without making an HTTP request, or we can keep this all in one but use request mocking to inspect and validate the token: https://github.com/sindresorhus/got#testing