From 64ab35fa4a18c1bbc2a219ab4e28f8cafba2eea1 Mon Sep 17 00:00:00 2001 From: kelsk Date: Thu, 2 Apr 2020 21:15:04 -0700 Subject: [PATCH 1/2] Add service-to-service Node.js sample --- run/authentication/auth.js | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 run/authentication/auth.js diff --git a/run/authentication/auth.js b/run/authentication/auth.js new file mode 100644 index 0000000000..c152408e4a --- /dev/null +++ b/run/authentication/auth.js @@ -0,0 +1,52 @@ +// Copyright 2019 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. + +// [START run_service_to_service_auth] +// Make sure to `npm install gcp-metadata` and `npm install got` or add the dependencies to your package.json +const gcpMetadata = require('gcp-metadata') +const got = require('got'); + +const requestServiceToken = async () => { + try { + + // Add the URL of your receiving service + const receivingServiceURL = ... + + // Set up the metadata server request options + // See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature + const metadataServerTokenPath = 'service-accounts/default/identity?audience=' + receivingServiceURL; + const tokenRequestOptions = { + headers: { + 'Metadata-Flavor': 'Google' + } + }; + + // Fetch the token and then provide it in the request to the receiving service + const tokenResponse = await gcpMetadata.instance(metadataServerTokenPath, tokenRequestOptions); + const serviceRequestOptions = { + headers: { + 'Authorization': 'bearer ' + tokenResponse + } + }; + + const serviceResponse = await got(receivingServiceURL, serviceRequestOptions); + res.send(serviceResponse.body); + + } catch (error) { + console.log('Metadata server could not respond to query ', error); + res.send(error); + } +}; + +// [END run_service_to_service_auth] \ No newline at end of file From 86b0635f62c161c44a1bd19f404ab2b6b3a6acde Mon Sep 17 00:00:00 2001 From: kelsk Date: Fri, 3 Apr 2020 14:48:17 -0700 Subject: [PATCH 2/2] Update sample to address suggested changes --- run/authentication/auth.js | 27 ++++++++++++++++----------- run/authentication/package.json | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 run/authentication/package.json diff --git a/run/authentication/auth.js b/run/authentication/auth.js index c152408e4a..6411bea0fb 100644 --- a/run/authentication/auth.js +++ b/run/authentication/auth.js @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// 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. @@ -12,19 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. +function main(receivingServiceURL = 'YOUR_RECEIVING_SERVICE_URL') { // [START run_service_to_service_auth] -// Make sure to `npm install gcp-metadata` and `npm install got` or add the dependencies to your package.json + +// Import the Metadata API const gcpMetadata = require('gcp-metadata') const got = require('got'); +// TODO(developer): Add the URL of your receiving service +// const receivingServiceURL = 'YOUR_RECEIVING_SERVICE_URL'' + const requestServiceToken = async () => { try { - // Add the URL of your receiving service - const receivingServiceURL = ... - // Set up the metadata server request options - // See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature const metadataServerTokenPath = 'service-accounts/default/identity?audience=' + receivingServiceURL; const tokenRequestOptions = { headers: { @@ -33,20 +34,24 @@ const requestServiceToken = async () => { }; // Fetch the token and then provide it in the request to the receiving service - const tokenResponse = await gcpMetadata.instance(metadataServerTokenPath, tokenRequestOptions); + const token = await gcpMetadata.instance(metadataServerTokenPath, tokenRequestOptions); const serviceRequestOptions = { headers: { - 'Authorization': 'bearer ' + tokenResponse + 'Authorization': 'bearer ' + token } }; const serviceResponse = await got(receivingServiceURL, serviceRequestOptions); - res.send(serviceResponse.body); + return serviceResponse; } catch (error) { console.log('Metadata server could not respond to query ', error); - res.send(error); + return error; } }; -// [END run_service_to_service_auth] \ No newline at end of file +// [END run_service_to_service_auth] + +requestServiceToken(); +}; +main(); \ No newline at end of file diff --git a/run/authentication/package.json b/run/authentication/package.json new file mode 100644 index 0000000000..58ae47bb48 --- /dev/null +++ b/run/authentication/package.json @@ -0,0 +1,21 @@ +{ + "name": "nodejs-auth", + "version": "1.0.0", + "description": "Cloud Run service-to-service authentication", + "main": "index.js", + "private": true, + "scripts": { + "start": "node index.js", + "test": "test" + }, + "author": "krippaehne", + "license": "Apache-2.0", + "dependencies": { + "express": "^4.16.4", + "gcp-metadata": "^4.0.0", + "got": "^10.7.0" + }, + "devDependencies": { + "mocha": "^7.0.0" + } +}