GCP API Gateway

Create an API config that protects routes with Passage.

Prerequisites

Configuring the gateway

In GCP, you define the routes for the API Gateway in a configuration file that follows the OpenAPI specification. API Gateways and configs can be created and managed via the console or the CLI tool.

Below is an example API config that defines a OpenAPI security definition using Passage. You will need your Passage App ID and auth origin to configure your security definition, which can be found in the Passage Console settings. In this example, only the GET request to /user needs to be authenticated, so we add the security section at the method level to protect that route. You can also add the security section to apply to the entire API.

swagger: '2.0'
info:
    title: user-gateway
    description: Sample API Gateway with a Google Cloud Function backend
    version: 1.0.0
paths:
    /user:
        get:
            operationId: getUser
            x-google-backend:
                address: <CLOUD_FUNCTION_URL>
            # This 'security' section enables the security definition set up below.
            security:
                - passage: []
            responses:
                '200':
                    description: A successful response
        options:
            operationId: cors
            x-google-backend:
                address: <CLOUD_FUNCTION_URL>
            responses:
                '200':
                    description: A successful response
 
securityDefinitions:
    # This 'passage' security definition enables the Passage JWKS endpoint
    # to be used to verify JWTs.
    passage:
        authorizationUrl: ''
        flow: 'implicit'
        type: 'oauth2'
        # The 'iss' parameter of the JWT to be verified. In this case, your App ID.
        x-google-issuer: 'YOUR_PASSAGE_APP_ID'
        # The JWKS URL Passage provides for your App ID.
        x-google-jwks_uri: 'https://auth.passage.id/v1/apps/YOUR_PASSAGE_APP_ID/.well-known/jwks.json'
        # The 'aud' parameter of the JWT to be verified.
        # The URL where your app is hosted - the auth origin
        x-google-audiences: 'YOUR_AUTH_ORIGIN'

If the JWT for a particular request does not validate, the gateway will return a 401.

Access the user info

Once the API Gateway successfully authenticates a request, the JWT claims will be available to whatever service is used for the server functionality via a request header added by the gateway. The header key name is x-apigateway-api-userinfo.

For example, if you had a Cloud Function where you wanted to fetch user information from Passage for the authenticated user, it would look like this:

const { Passage } = require('@passageidentity/passage-node');
 
exports.user = async (req, res) => {
    // add CORS headers
    res.set('Access-Control-Allow-Origin', '*');
    res.set('Access-Control-Allow-Headers', '*');
    res.set('Access-Control-Allow-Methods', 'GET');
 
    // extract JWT from original request forwarded by API Gateway to get the
    // Passage User ID
    const userInfo = req.headers['x-apigateway-api-userinfo'];
    const jwtPayload = JSON.parse(new Buffer(userInfo, 'base64').toString('ascii'));
    const userID = jwtPayload.sub;
 
    //initialize Passage with preset env vars
    const passage = new Passage({
        appID: process.env.PASSAGE_APP_ID,
        apiKey: process.env.PASSAGE_API_KEY,
    });
 
    // fetch user from Passage
    const user = await passage.user.get(userID);
 
    return res.status(200).json(user);
};

References

GCP API Gateway Docs - Using JWT to Authenticate Users (opens in a new tab)