Skip to main content

Edge Authentication

Context

Implementing authentication at the edge helps to decrease the complexity of your services and provides an extra security layer as it reduces the burden of authentication from the individual service owner.

Edge authentication helps removing middleware from your infrastructure and provides an easy and centralized way to manage authentication and authorization policies for your whole infrastructure.

Limitations

If you want to protect static files or server-side rendered applications (written in JavaScript, PHP, Ruby, Django, etc.), please check Protecting resources with Authentication Proxy.

Solution

There are two ways to achieve and implement authentication at the edge with Gate which can be combined together or run independently and can be controlled on a per URL basis. The first relies on JWT tokens issued by SlashID and the second is more generic and can be implemented with any JWT token issuer.

As a prerequisite, you should have Gate deployed in your infrastructure.

Validating of JWT on the edge

SlashID-issued JWT tokens can be validated by the JWT verification plugin.

SlashID APISignInHTTP Only Cookie with JWTHTTP Only Cookie with JWTVerificationresultVerifyJWT(optional)UserYour systemLoad balancerDestination endpointGateUnauthenticatedrequestHTTP request?

To validate JWTs issued by SlashID:

GATE_PLUGINS_<PLUGIN NUMBER>_TYPE=validate-jwt
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_SLASHID_ORG_ID=<SlashID Org ID>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_SLASHID_API_KEY=<SlashID API key>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_SLASHID_BASE_URL=<SlashID base URL>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_SLASHID_REQUIRED_GROUPS=<Required SlashID groups list>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_SLASHID_MAX_GROUPS_INFO_AGE=<Max SlashID groups info age>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_HEADER_WITH_TOKEN=<Header with token>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_COOKIE_WITH_TOKEN=<Cookie with token>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_TOKEN_SCHEMA=<Token schema>

In the Environment variables configuration, <PLUGIN NUMBER> defines plugin execution order.

To validate JWTs issued by a third party:

GATE_PLUGINS_<PLUGIN NUMBER>_TYPE=validate-jwt
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_JWKS_URL=<Custom JSON Web Key Sets URL>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_JWKS_REFRESH_INTERVAL=<JSON Web Key Sets refresh interval>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_JWT_ALLOWED_ALGORITHMS=<Allowed JWT signing algorithms>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_JWT_EXPECTED_ISSUER=<JWT expected issuer>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_JWT_EXPECTED_AUDIENCE=<JWT expected audience>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_HEADER_WITH_TOKEN=<Header with token>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_COOKIE_WITH_TOKEN=<Cookie with token>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_TOKEN_SCHEMA=<Token schema>

In the Environment variables configuration, <PLUGIN NUMBER> defines plugin execution order.

Where:

  • <SlashID Org ID> your SlashID organization ID. If provided, this will be used as the JWT audience.
  • <SlashID API key> your SlashID API key.
  • <SlashID base URL> base URL of the SlashID API. If provided, this will be used as the JWT issuer and JWKS URL.
  • <Required SlashID groups list> list of groups required to access the endpoint. By default, empty (no groups required). If multiple groups are provided, all of them are required. In environment variables multiple groups should be separated by a comma. For example: user,admin. In HCL, JSON, TOML and YAML, multiple groups should be provided as a list. For example: ["user", "admin"].
  • <Max SlashID groups info age> maximum age of SlashID groups information. If groups are present in the JWT, but their information is older than this value, Gate will fetch the latest information from SlashID servers. Age should have format 1h, 1m, 1s or 1ms. You can combine multiple units, for example: 1h30m. If not provided, groups information will be fetched from SlashID servers on every request.
  • <Custom JSON Web Key Sets URL> URL of key sets used for offline token validation.
  • <JSON Web Key Sets refresh interval> interval for refreshing key sets used for offline token validation. By default, 15m.
  • <Allowed JWT signing algorithms> list of allowed signing algorithms for JWTs. At least one algorithm must be provided. Only JWTs with one of these algorithms in the alg field will be accepted; requests with JWTs using another algorithm will be rejected. In environment variables, multiple algorithms should be separated by a comma. For example: ES256,ES512. In HCL, JSON, TOML and YAML, multiple algorithms should be provided as a list. For example: ["ES256", "ES512"]. This plugin supports the following algorithms: ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512.
  • <JWT expected issuer> expected issuer of the JWT token.
  • <JWT expected audience> expected audience of the JWT token.
  • <Header with token> is the request header containing the token. This option and cookie_with_token are mutually exclusive.
  • <Cookie with token> is the request cookie containing the token. This option and header_with_token are mutually exclusive.
  • <Token schema> a JSON or YAML schema for the JWT payload

To learn more about configuring Gate, please visit configuration page and plugins section.

info

The order of plugins in configuration determines their execution order.

Disabling plugin for specific URLs

You can enable or disable this plugin for specific URLs by using the enabled option in the URLs configuration.

GATE_URLS_0_PATTERN=svc-example.com/*
GATE_URLS_0_TARGET=http://example:8080

GATE_URLS_1_PATTERN=svc-another-example.com/
GATE_URLS_1_TARGET=https://another-example:8080

You can find the complete plugin reference in the JWT verification plugin page.

Integrating with SlashID SDK

You need a valid JWT token issued by SlashID to make requests validated by the JWT validation plugin. The easiest way to obtain it, is using our JavaScript/TypeScript SDK.

Custom validation logic

If you want to implement custom logic for your endpoints, you can achieve it with Request Validator plugin. With that plugin, you can implement custom validation logic as a custom endpoint on your side.

Yourrequest validation endpointValidationresultHTTP requestheadersUserYour systemLoad balancerDestination endpointGateHTTP requestHTTP request?
GATE_PLUGINS_<PLUGIN NUMBER>_TYPE=request-validator
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_VALIDATE_URL=<URL of validation endpoint>

In the Environment variables configuration, <PLUGIN NUMBER> defined plugin execution order.

where:

  • <URL of validation endpoint> URL to be called by the plugin.

To learn more about configuring Gate, please visit the configuration page and plugins section.

info

The order of plugins in configuration determines their execution order.

Validation endpoint

The configured endpoint is called on every request with the GET method. All headers of the original request are forwarded to the validation endpoint. Two additional headers are included in the request:

  • SlashID-Target-Method
  • SlashID-Target-Location

These carry the method and location of the original request, respectively.

If the endpoint returns 2XX status code, the request is considered as valid. If 5XX HTTP status is returned, Gate will respond with 502 Bad Gateway HTTP status. In all other cases, Gate will return 401 Unauthorized.

note

Requests with the OPTIONS method are not validated and are always valid.

Disabling plugin for specific URLs

You can enable or disable this plugin for specific URLs by using the enabled option in the URLs configuration.

GATE_URLS_0_PATTERN=svc-example.com/*
GATE_URLS_0_TARGET=http://example:8080

GATE_URLS_1_PATTERN=svc-another-example.com/
GATE_URLS_1_TARGET=https://another-example:8080

You can find complete plugin reference on the Request Validator plugin page.

Example

Configuring Gate

This is an example configuration for Gate such that when a user navigates to */api/generic, Gate generates a new user in SlashID.

slashid_config: &slashid_config
slashid_org_id: { { .env.SLASHID_ORG_ID } }
slashid_api_key: { { .env.SLASHID_API_KEY } }
slashid_base_url: { { .env.SLASHID_BASE_URL } }

gate:
port: 8080
log:
format: text
level: trace

default:
target: http://backend:8000

plugins:
- id: validator
type: validate-jwt
enable_http_caching: true
enabled: false
parameters:
<<: *slashid_config
jwks_url: https://api.sandbox.slashid.com/.well-known/jwks.json
jwks_refresh_interval: 15m
jwt_expected_issuer: https://api.sandbox.slashid.com

urls:
# The /api/generic endpoint uses the validator plugin to verify the SlashID jwt token befere the requests reaches the endpoint
- pattern: "*/api/generic"
target: http://backend:8000
plugins:
validator:
enabled: true

Any requests reaching */api/generic without a valid SlashID JWT token will be blocked by Gate.