Skip to content

Instantly share code, notes, and snippets.

@plmrry
Last active July 28, 2020 09:53
Show Gist options
  • Save plmrry/f78136bba68f810622bc2840497ef7e1 to your computer and use it in GitHub Desktop.
Save plmrry/f78136bba68f810622bc2840497ef7e1 to your computer and use it in GitHub Desktop.
Node.js GCP IAP Service Account Authentication
const request = require('request');
const jws = require('jws');
const OAUTH_TOKEN_URI = 'https://www.googleapis.com/oauth2/v4/token';
const APP_HOST = process.env.APP_HOST;
const APP_URI = `https://${APP_HOST}`;
const creds = require('./service_account');
var iat = Math.floor(new Date().getTime() / 1000);
var exp = iat + 3600;
var payload = {
iss: creds.client_email,
aud: "https://www.googleapis.com/oauth2/v4/token",
exp,
iat,
target_audience: APP_URI,
};
var assertion = {
header: {
alg: 'RS256',
typ: 'JWT'
},
payload: payload,
secret: creds.private_key
};
const jwt = jws.sign(assertion);
const body = `assertion=${jwt}&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer`;
request({
method: 'POST',
uri: 'https://www.googleapis.com/oauth2/v4/token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body
}, function(err, response, body) {
const parsed = JSON.parse(body);
const { id_token } = parsed;
request({
method: 'POST',
uri: APP_URI,
headers: {
Authorization: `Bearer ${id_token}`,
'Content-Type': "application/json"
},
body: JSON.stringify({ foo: "bar" })
}, function(err, response, body) {
console.log(err);
console.log(response.headers);
console.log(body);
})
})
@ryanchapman
Copy link

ryanchapman commented Jan 5, 2019

After working on this for a few hours, just wanted to leave a note for others...

target_audience in the payload needs to be the the oauth client ID which looks like 64456944346-t71n9gg0pps1p251pa9a4nl505k212sl.apps.googleusercontent.com (without http:// or https://)

(your client ID can be found in GCP Console > Security > Identity Aware Proxy, click three dots beside your load balancer, Edit OAuth Client, Client ID)

If anyone knows of a way to use the public FQDN of the load balancer (like https://api.initech.com/) in the target_audience, please let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment