Gate: Plugin - HttpOnly cookies
This plugin adds support for HTTP-only cookie-based authentication.
With this plugin, your multi-page application can delegate authentication to Gate and protect against client-side token exfiltration attacks.
Cookies are limited to 4 kB in size. When over the limit, browsers ignore
Set-Cookie
instructions. This may result in failed sign in attempts by your
users.
At the moment, Gate does not monitor the size of the cookie.
Example usage
Please see API authentication at the edge.
Configuring Gate
- Environment variables
- HCL
- JSON
- TOML
- YAML
GATE_PLUGINS_<PLUGIN NUMBER>_TYPE=httpOnly-proxy
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_CAN_CREATE_HTTP_ONLY=<Can create a new HTTP-only entry?>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_ALLOW_UNAUTHENTICATED_REQUESTS=<Allow unauthenticated requests?>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_FAILED_AUTHENTICATION_ENDPOINT="<Redirect client to this endpoint when authentication failed>"
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_SECRET_KEY_BASE="<Secret key base>"
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_COOKIE_NAME="<HTTP-Only cookie name>"
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_REQUIRED_GROUPS=<Required SlashID groups list>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_MAX_GROUPS_INFO_AGE=<Max groups info age>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_ONLINE_TOKENS_VALIDATION=<Validate tokens with SlashID servers>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_ONLINE_TOKENS_VALIDATION_TIMEOUT=<Validate tokens with SlashID servers timeout>
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_EXPECTED_ISSUER=<JWT expected issuer>
In the Environment variables configuration, <PLUGIN NUMBER>
defined plugin execution order.
gate = {
plugins = [
// ...
{
type = "httpOnly-proxy"
parameters = {
slashid_org_id = "<SlashID Org ID>"
slashid_base_url = "<SlashID base URL>"
can_create_http_only = <Can create a new HTTP-only entry?>
allow_unauthenticated_requests = <Allow unauthenticated requests?>
failed_authentication_endpoint = "<Redirect client to this endpoint when authentication failed>"
secret_key_base = "<Secret key base>"
cookie_name = "<HTTP-Only cookie name>"
required_groups = "<Required SlashID groups list>"
max_groups_info_age = "<Max groups info age>"
online_tokens_validation = "<Validate tokens in online way>"
online_tokens_validation_timeout = "<Validate tokens with SlashID servers timeout>"
jwks_url = "<Custom JSON Web Key Sets URL>"
jwks_refresh_interval = "<JSON Web Key Sets refresh interval>"
jwt_expected_issuer = "<JWT expected issuer>"
}
}
// ...
]
}
{
"gate": {
"plugins": [
// ...
{
"type": "httpOnly-proxy",
"parameters": {
"slashid_org_id": "<SlashID Org ID>",
"slashid_base_url": "<SlashID base URL>",
"can_create_http_only": <Can create a new HTTP-only entry?>,
"allow_unauthenticated_requests": <Allow unauthenticated requests?>,
"failed_authentication_endpoint": "<Redirect client to this endpoint when authentication failed>",
"secret_key_base": "<Secret key base>",
"cookie_name": "<HTTP-Only cookie name>",
"required_groups": "<Required SlashID groups list>",
"max_groups_info_age": "<Max groups info age>",
"online_tokens_validation": "<Validate tokens in online way>",
"online_tokens_validation_timeout": "<Validate tokens with SlashID servers timeout>",
"jwks_url": "<Custom JSON Web Key Sets URL>",
"jwk_refresh_interval": "<JSON Web Key Sets refresh interval>",
"jwt_expected_issuer": "<JWT expected issuer>"
}
}
// ...
]
}
}
[[gate.plugins]]
type = "httpOnly-proxy"
parameters.slashid_org_id = "<SlashID Org ID>"
parameters.slashid_base_url = "<SlashID base URL>"
parameters.can_create_http_only = <Can create a new HTTP-only entry?>
parameters.allow_unauthenticated_requests = <Allow unauthenticated requests?>
parameters.failed_authentication_endpoint = "<Redirect client to this endpoint when authentication failed>"
parameters.secret_key_base = "<Secret key base>"
parameters.cookie_name = "<HTTP-Only cookie name>"
parameters.required_groups = "<Required SlashID groups list>"
parameters.max_groups_info_age = "<Max groups info age>"
parameters.online_tokens_validation = "<Validate tokens in online way>"
parameters.online_tokens_validation_timeout = "<Validate tokens with SlashID servers timeout>"
parameters.jwks_url = "<Custom JSON Web Key Sets URL>"
parameters.jwk_refresh_interval = "<JSON Web Key Sets refresh interval>"
parameters.jwt_expected_issuer = "<JWT expected issuer>"
gate:
plugins:
// ...
- type: httpOnly-proxy
parameters:
slashid_org_id: <SlashID Org ID>
slashid_base_url: <SlashID base URL>
can_create_http_only: <Can create a new HTTP-only entry?>
allow_unauthenticated_requests: <Allow unauthenticated requests?>
failed_authentication_endpoint: <Redirect client to this endpoint when authentication failed>
secret_key_base: <Secret key base>
cookie_name: <HTTP-Only cookie name>
required_groups: <Required SlashID groups list>
max_groups_info_age: <Max groups info age>
online_tokens_validation: <Validate tokens in online way>
online_tokens_validation_timeout: <Validate tokens with SlashID servers timeout>
jwks_url: <Custom JSON Web Key Sets URL>
jwk_refresh_interval: <JSON Web Key Sets refresh interval>
jwt_expected_issuer: <JWT expected issuer>
// ...
where:
<SlashID Org ID>
your SlashID organization ID<SlashID base URL>
base URL of SlashID servers. By default,https://api.slashid.com
.<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 roles should be separated by a comma. For example:user,admin
. In HCL, JSON, TOML and YAML multiple roles should be provided as a list. For example:["user", "admin"]
.<Can create a new HTTP-only entry?>
if enabled, the URL is allowed to create new HTTP-only entries.<Allow unauthenticated requests?>
if enabled, the URL is allowed to receive unauthenticated requests. It will still receive existing HTTP-only entries. This is useful for pages like your sign-in page: it must not prompt the user for authentication when they're authenticated.<Redirect client to this endpoint when authentication failed>
if the URL requires authentication but there no HTTP-only entries in the ruquest.<Secret base key>
a 64-char long hex encoded string that must be generated using a cryptographically-strong number generator. This key is used to derive per-message keys that are used to encrypt the HTTP-only entries contained in the cookie.<HTTP-only cookie name>
the name of the cookie containing HTTP-only entries.<Max groups info age>
maximum age of groups information. If groups are present in JWT or in cache, but their information is older than this value, Gate will fetch the latest information from SlashID servers. Age should have format1h
,1m
,1s
or1ms
. You can combine multiple units, for example:1h30m
. If not provided, groups information will be fetched from SlashID servers on every request.<Validate tokens with SlashID servers>
if enabled, JWT tokens will be validated with SlashID servers for each request. It will introduce a slight latency overhead for each request, but it guarantees data freshness and accounts for activity on the identity object (disabled account, groups and roles changes and similar). To help to measure the impact of this option on your request, we recommend checking the Gate Monitoring guide. If disabled, Gate verifies the JWT signature and expiration without making any external call.true
by default.<Validate tokens with SlashID servers timeout>
timeout for validating tokens with SlashID servers. By default,5s
. If the timeout is reached, the request will be rejected with502 Bad Gateway
status code.<Custom JSON Web Key Sets URL>
URL of key sets used for offline token validation. By default, SlashID key sets are used.<JSON Web Key Sets refresh interval>
interval for refreshing key sets used for offline token validation. By default,15m
.<JWT expected issuer>
expected issuer of the JWT token. By default,https://api.slashid.com
.
To learn more about configuring Gate, please visit configuration page and plugins section.
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.
- Environment variables
- HCL
- JSON
- TOML
- YAML
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
gate = {
urls = [
{
pattern = "svc-example.com/*"
target = "http://example:8080"
},
{
pattern = "svc-another-example.com/"
target = "https://another-example:8080"
}
]
// ...
}
{
"gate": {
"urls": [
{
"pattern": "svc-example.com/*",
"target": "http://example:8080",
},
{
"pattern": "svc-another-example.com/",
"target": "https://another-example:8080"
}
],
// ...
URL are matched in the order they are defined in the configuration file.
[[gate.urls]]
pattern = "svc-example.com/*"
target = "http://example:8080"
[[gate.urls]]
pattern = "svc-another-example.com/"
target = "https://another-example:8080"
URL are matched in the order they are defined in the configuration file.
gate:
urls:
- pattern: svc-example.com/*
target: http://example:8080
- pattern: svc-another-example.com/
target: https://another-example:8080
URL are matched in the order they are defined in the configuration file.
Here's an example:
gate = {
log = {
format = "text"
level = "trace"
}
default = {
target = "https://example.com"
}
plugins = [
{
enabled = false
type = "httpOnly-proxy"
id = "HTTPONLY_PROXY"
parameters = {
slashid_org_id = "00000000-0000-0000-0000-000000000000"
slashid_base_url = "https://api.slashid.com"
failed_authentication_endpoint = "/failed-auth"
secret_key_base = "0000000000000000000000000000000000000000000000000000000000000000"
jwks_url = "https://api.slashid.com/.well-known/jwks.json"
jwks_refresh_interval = "3600s"
jwt_expected_issuer = "123"
online_tokens_validation_timeout = "3600s"
}
}
]
urls = [
{
pattern = "service.internal/create-httponly"
target = "https://example.com"
plugins = {
"HTTPONLY_PROXY" = {
enabled = true
parameters = {
can_create_httpOnly = true
}
}
}
},
{
pattern = "service.internal/sign-in"
target = "https://example.com"
plugins = {
"HTTPONLY_PROXY" = {
enabled = true
parameters = {
allow_unauthenticated_requests = true
}
}
}
},
{
pattern = "service.internal/private-page"
target = "https://example.com"
plugins = {
"HTTPONLY_PROXY" = {
enabled = true
parameters = {
allow_unauthenticated_requests = false
}
}
}
},
{
pattern = "service.internal/sign-out"
target = "https://example.com"
plugins = {
"HTTPONLY_PROXY" = {
enabled = true
parameters = {
allow_unauthenticated_requests = false
}
}
}
}
]
}