Welcome to the new Golem Cloud Docs! 👋
Make APIs Secure

Make Secure HTTP APIs

Golem API gateway has built-in authentication support to identify users using OpenID protocol. This allows you to refer to the claims such as request.auth.email (as an example) once authenticated in your Rib expression. You can choose to pass this information into the worker function that exist in the Rib expression, and do further logic with it. Currently, this is tested with Google Identity connector.

Setup Security for your API routes in Golem

Register an app with Google Identity Provider and get a client-id and client-secret.

Here is the direct link to register your app with Google Identity Provider (opens in a new tab). Make sure your app with a redirect URL and get the client-id and client secret.

If you are going with this example, the redirect URI can be http://localhost:9006/auth/callback

If you are not using OSS, then the redirect URI can be https://mydomain.com/auth/callback, where mydomain.com is the domain in which you will be deploying your API definition in Golem.

The /auth/callback part is just an example and it can be anything, as far as it doesn't collide with any of your other paths.

We call these details "Api Security Scheme" in Golem API Gateway. Next step is to register this detail with Golem

Register API Security Scheme with your app's client-id and client-secret with Golem

Make sure you name your security scheme uniquely, and provide the client-id, client-secret and redirect-url as given below.

 
golem api security-scheme create \
  --provider-type google \
  --client-id REPLACE_WITH_GOOGLE_CLIENT_ID \
  --client-secret REPLACE_WITH_GOOGLE_CLIENT_SECRET \
  --redirect-url http://localhost:9006/auth/callback
  --scope openid,email,profile \
  my-security

By now, you are having a security scheme registered with golem which you can refer in API definitions.

Reference the security scheme name in API definition

We updated the second route with security configuration created above which is my-security and updated the Rib script to use request.auth.email as an authenticated route have access to the details of the user

Here is the golem.yaml that we have been using, and you see the difference in the second route, where we added the security field with the name my-security and the Rib script to use request.auth.email to get the email of the user.

Our security scheme above has a scope of openid,email,profile allowing us to lookup email in Rib script.

# Schema for IDEA:
# $schema: https://schema.golem.cloud/app/golem/1.2.2-dev.1/golem.schema.json
# Schema for vscode-yaml
# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.2.2-dev.1/golem.schema.json
 
# See https://learn.golem.cloud/docs/app-manifest#field-reference for field reference
 
components:
  amazon:shopping-cart:
    template: rust
 
httpApi:
  definitions:
    shopping-cart:
      version: '0.0.2'
      routes:
        - method: POST
          path: /v1/{user}/add-to-cart
          binding:
            type: default
            componentName: "amazon:shopping-cart"
            response: |
              let user: u32 = request.path.user;
              let worker = instance("cart-${user}");
              worker.add-item(request.body);
              "successfully added item to the cart"
        - method: GET
          path: /v1/{user}/contents
          security: my-security
          binding:
            type: default
            componentName: "amazon:shopping-cart"
            response: |
              let user: u32 = request.path.user;
              let worker = instance("cart-${user}");
              let user-name: string = request.auth.email;
              {
                user: user-name,
                cart: worker.get-cart-contents()
              }
        - method: POST
          path: /v1/{user}/checkout
          binding:
            type: default
            componentName: "amazon:shopping-cart"
            response: |
              let user: u32 = request.path.user;
              let worker = instance("cart-${user}");
              worker.checkout()
 
  # Uncomment if you want to deploy your api
  deployments:
    local:
    - host: localhost:9006
      definitions:
       - shopping-cart
The new fields in request object
let user: u32 = request.path.user;
let worker = instance("cart-${user}");
let user-name: string = request.auth.email;
{
   user: user-name,
   cart: worker.get-cart-contents()
}

In the Rib script, we are expecting a field called auth with the email of the user, and this is populated. Unlike request.path.*, request.query.*, request.auth.* is valid only in a route with security enabled.

Deploy and test

golem app deploy
 

Open browser (preferably chrome as we haven't extensively tested across all browsers) and try http://localhost:9006/v1/100/contents (opens in a new tab). This should redirect you to google login, to authenticate yourself, to finally get the result such as the following

{
  "cart":[{"name":"foo","price":42.0,"product-id":"foo","quantity":42},{"name":"foo","price":42.0,"product-id":"foo","quantity":42},{"name":"foo","price":42.0,"product-id":"foo","quantity":42},{"name":"foo","price":42.0,"product-id":"foo","quantity":42}],
  "user":"me.anonymous@gmail.com"
}
 

Redirects and Cookies

Internally, there are a couple of redirects that's going on when you access the protected endpoint. The first redirect is to the Google Identity Provider login page as explained below, and internally this is followed by identity provider hitting the redirect URL ( which is exposed on your behalf by Golem API gateway) with all the details of the user. This is followed by another redirect to the original URL that you tried to access, and this time the session-id, tokens/secrets set in a secure Cookie, which your browser will resend. Once the browser sends the cookie, Golem API gateway will validate the cookie and allow you to access the protected endpoint.

We will be adding more support for various clients and usecases in future releases based on the user feedback.

Unexposed CallBack Endpoint

Note that the callback endpoint is exposed automatically based on the re-direct url specified in the API security scheme. Users cannot customise or add these call back endpoints manually. This is to avoid any security issues that may arise due to misconfiguration of the callback endpoint.

Troubleshoot

Most of the errors in this usecase are originated from a wrong security scheme configuration. For example, a wrong redirect-url can result in odd errors that is difficult to spot, as this is originated from the providers and not Golem.

Make sure the scope is correct and includes email. Trying to specify request.auth.email while the scope doesn't have it in the security scheme, will result in errors such as email not found in the request object

Known Issues

If you try to update golem with multiple security schemes (with the names foo-security-scheme, and bar-security-scheme ) but with the same redirect-url, you will get an internal repository error. This will be fixed in the upcoming releases.

Selected profile: local
 
error: API Security Scheme Service - Error: 500 Internal Server Error, InternalError: Internal repository error (unique
     key violation)