Skip to content

Instantly share code, notes, and snippets.

@jasonpolites
Last active November 3, 2017 20:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasonpolites/542ab16a94be9eade7382b6744ce5908 to your computer and use it in GitHub Desktop.
Save jasonpolites/542ab16a94be9eade7382b6744ce5908 to your computer and use it in GitHub Desktop.
[Very] Rough example of how to sign a JWT in GCF
const rp = require('request-promise');
exports.generateJwt = (req, res) => {
let serviceNamePromise = getServiceAccountName();
let serviceTokenPromise = getServiceAccountToken();
Promise.all([
serviceNamePromise,
serviceTokenPromise]).then((values) => {
let projectId = process.env.GCLOUD_PROJECT;
let DEFAULT_SERVICE_ACCOUNT = values[0];
let accessToken = JSON.parse(values[1]).access_token;
let now = Date.now() / 1000;
// Copied mostly from https://cloud.google.com/endpoints/docs/openapi/service-to-service-auth#using_a_jwt_signed_only_by_the_service_account
let jwt = JSON.stringify({
'iat': parseInt(now),
// expires after one hour.
"exp": parseInt(now + 3600),
// iss is the default service account email.
'iss': DEFAULT_SERVICE_ACCOUNT,
'sub': DEFAULT_SERVICE_ACCOUNT,
// aud must match 'audience' in the security configuration in your
// OpenAPI spec.It can be any string.
'aud': 'echo.endpoints.sample.google.com',
"email": DEFAULT_SERVICE_ACCOUNT
});
signJwt(jwt, projectId, DEFAULT_SERVICE_ACCOUNT, accessToken).then((result) => {
res.send(result);
}, (err) => {
handleError(res, err);
});
}, (err) => {
handleError(res, err);
}, (err) => {
handleError(res, err);
});
}
function handleError(res, err) {
res.status(400).send(err);
}
function getServiceAccountName() {
return rp({
uri: 'http://metadata/computeMetadata/v1/instance/service-accounts/default/email',
headers: {
'Metadata-Flavor': 'Google'
}
});
}
function getServiceAccountToken() {
return rp({
uri: 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token',
headers: {
'Metadata-Flavor': 'Google'
}
});
}
function signJwt(jwt, projectId, serviceAccount, accessToken) {
console.log(`Attempting to sign jwt ${jwt} for project ${projectId} on service account ${serviceAccount} with token ${accessToken}`);
let uri = `https://iam.googleapis.com/v1/projects/${projectId}/serviceAccounts/${serviceAccount}:signJwt`;
let bearerToken = `Bearer ${accessToken}`;
return rp({
method: 'POST',
uri: uri,
headers: {
'Authorization': bearerToken
},
body: {
'payload': jwt
},
json: true
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment