Summary
I'll be showing some of the detailed configuration necessary to deploy API Gateway with a Cloud Functions back-end and authentication for a non-human (machine) client. I'll be focusing on the front and back-end authentication configuration. I'll also be showing the client side in Node.js which is very thinly documented by Google.
Architecture
Authentication
Back-end: Cloud Functions
The back-end GCF is deployed requiring authentication. The API Gateway is configured to operate under a Service Account that has the Cloud Function Invoker role.
Front-end: Machine Client
Configuration here is significantly more complicated than the back-end. Configuration areas:
- A Service Account needs to be created and a SA key downloaded. That key is then used to sign a JWT for authentication to the API Gateway.
- Security definitions must be added to OpenAPI spec (Swagger 2.0) that specify that SA as an allowed user.
- The Machine Client itself must generate a JWT to the API Gateway specs and sign that JWT with the SA key.
Code
OpenAPI Security Definition
securityDefinitions:
machine-service:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "machine-service@kvpstore.iam.gserviceaccount.com"
x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/machine-service@kvpstore.iam.gserviceaccount.com"
security:
- machine-service: []
Machine Client-side
'use strict';
const fetch = require('node-fetch');
const jwt = require('jsonwebtoken');
const sakey = require('./sakey.json'); //json file downloaded from Google IAM
const EMAIL = sakey.client_email;
const AUDIENCE = 'your audience';// this value corresponds to the "Managed service" name of the API Gateway
const ALGORITHM = 'RS256';
const GWY_URL = 'your URL';
const KEY = sakey.private_key
function exampleAPICall(email, audience, key, algorithm) {
const payload = {
iat: Date.now(),
exp: Date.now() + 3600,
iss: email,
aud: audience,
sub: email,
email: email
}
const token = jwt.sign(payload, key, {algorithm: algorithm});
const response = await fetch(`${gwyurl}/guid`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
});
return await response.json();
}
Copyright ©1993-2024 Joey E Whelan, All rights reserved.
