Security
Security features allow you to configure how your application authenticates when communicating with other services through the gateway. You can set up machine-to-machine authentication for both API providers and consumers, and restrict access based on IP addresses.
Machine-to-Machine Authentication
Machine-to-machine (M2M) authentication is used when services communicate with each other without human involvement. By default, the Control Plane manages authentication between services automatically using platform-managed credentials. You can override this behavior by providing your own authentication configuration.
Applies to: API Exposure, API Subscription
OAuth2 Authentication (API Exposure)
As an API provider, you can configure the gateway to obtain an OAuth2 token from an external identity provider before forwarding requests to your backend. This is useful when your service requires a specific token format or scopes that differ from the platform-managed identity.
exposures:
- type: api
basePath: /checkout/v1
upstream: https://checkout.internal:8080
approval: SIMPLE
visibility: ENTERPRISE
security:
type: oauth2
tokenEndpoint: https://auth.example.com/oauth/token
grantType: CLIENT_CREDENTIALS
clientId: my-api-client
clientSecret: my-api-secret
OAuth2 Authentication (API Subscription)
As an API consumer, you can provide your own OAuth2 client credentials instead of relying on the platform-managed identity. This is necessary when the API provider requires credentials from a specific identity provider.
subscriptions:
- type: api
basePath: /checkout/v1
security:
type: oauth2
clientId: my-consumer-client
clientSecret: my-consumer-secret
OAuth2 Refresh Token (External IDP)
When an external identity provider issues a long-lived refresh token, you can supply it instead of (or in addition to) client credentials. The gateway then uses the refresh_token grant to obtain fresh access tokens from the external IDP without re-authenticating. This is useful for identity providers that require a user-consented refresh token rather than pure client credentials.
This is supported for both API providers (exposures) and consumers (subscriptions).
subscriptions:
- type: api
basePath: /checkout/v1
security:
type: oauth2
tokenEndpoint: https://auth.example.com/oauth/token
grantType: REFRESH_TOKEN
clientId: my-consumer-client
refreshToken: ${MY_REFRESH_TOKEN}
When grantType is REFRESH_TOKEN, provide the refreshToken field. Treat it as a secret and inject it via an environment variable placeholder (see the Handling Secrets note below).
For more information on the refresh token grant, see RFC 6749, Section 6.
Basic Authentication (API Exposure)
If your backend service uses basic authentication (username and password), you can configure the gateway to include these credentials when forwarding requests.
exposures:
- type: api
basePath: /checkout/v1
upstream: https://checkout.internal:8080
approval: SIMPLE
visibility: ENTERPRISE
security:
type: basicAuth
username: api-user
password: api-password
Basic Authentication (API Subscription)
As a consumer, you can also use basic authentication to access an API that requires it.
subscriptions:
- type: api
basePath: /checkout/v1
security:
type: basicAuth
username: consumer-user
password: consumer-password
Custom Scopes
When using OAuth2 authentication, you can request additional scopes to be included in the token. This is useful when the API provider requires specific scopes beyond the default platform scopes.
exposures:
- type: api
basePath: /checkout/v1
upstream: https://checkout.internal:8080
approval: SIMPLE
visibility: ENTERPRISE
security:
type: oauth2
scopes:
- read:orders
- write:orders
Scope Validation and External Identity Providers
API and agentic exposures and subscriptions support up to 100 M2M scopes. Rover M2M scopes are each limited to 256 characters.
For API and agentic (MCP and agent) exposures and subscriptions, configured M2M scopes normally must be declared in the corresponding specification. Matching is exact and case-sensitive.
When the active exposure has a non-empty external-IDP token endpoint, the Control Plane skips this specification check for both the exposure and its subscriptions. Scopes may then be absent from the specification, including when it declares no scopes at all. Each exposure and subscription continues to forward its own configured scopes; subscription scopes do not have to match the exposure's list.
In a Rover exposure, configure security.tokenEndpoint as shown in the OAuth2 example above. On the resulting ApiExposure or AgenticExposure custom resource, the relevant field is spec.security.m2m.externalIDP.tokenEndpoint:
spec:
security:
m2m:
externalIDP:
tokenEndpoint: https://auth.example.com/oauth/token
scopes:
- read:orders
The subscription inherits this exception from its active exposure. Subscriber credentials or a token endpoint configured elsewhere do not enable it. Removing the exposure's external-IDP configuration restores normal scope checking; an empty endpoint does not qualify for the exception.
Subscriber username/password credentials may be combined with scopes, client credentials or a grantType only when the selected exposure uses an external IDP; otherwise the subscription is blocked before approval. The subscription can set its own grantType; if it doesn't, the exposure's grant type applies. The gateway only uses subscriber credentials that can build a token request for this effective grant type: password needs username/password, refresh_token needs client credentials with a refresh token, and other grant types need client credentials. Client credentials are also sent with the password grant to authenticate the client. The subscription can also set its own tokenRequest to control how its client credentials are sent to the identity provider; if it doesn't, the exposure's tokenRequest applies. When the token is requested with the exposure's credentials, the exposure's tokenRequest is always used.
| Subscriber credentials | Effective grant | Result |
|---|---|---|
Username/password only, no grantType | any | Sent to the backend as HTTP Basic authentication |
| Credentials that match the effective grant | any | Used for the external-IDP token request; username/password only with the password grant |
| Scopes, or credentials that don't match the effective grant | any | The token is requested with the exposure's credentials, its grant type and the subscriber's scopes |
If an existing API or agentic subscription becomes invalid after its exposure's external IDP or scope policy changes, further processing is blocked and a Warning event explains the validation failure. Its existing ConsumeRoutes and active scopes are preserved; the invalid configuration is not applied. Restoring a valid configuration allows processing to resume, subject to approval. Revoking an approval still removes the subscription's ConsumeRoutes and clears its active scopes.
Cross-organization API subscriptions currently support scopes only. Client credentials and username/password credentials are not propagated by the remote-subscription flow and are blocked with a Warning event. Existing subscription-owned resources, active scopes and shared proxy routes are preserved.
Provider username/password credentials in spec.security.m2m.externalIDP require the password grant; otherwise the exposure is rejected. They may be combined with provider client credentials, which then authenticate the client in the password grant.
API approval requests still include the requested scopes. Existing readiness and approval requirements continue to apply, and the external identity provider determines whether it will grant the requested scopes.
Audience Claims
When a request reaches your backend service, it carries a security token. An audience claim (aud) tells the backend which service the token was intended for, so the backend can confirm it is the correct recipient before trusting the request.
As an API provider, you can require that every token reaching your backend contains a specific audience value. The claim applies to all consumers of the exposed API.
Applies to: API Exposure
You define the audience under the oauth2 security block, as claims.aud. You must set exactly one of the following:
value— a fixed text value that you choose.valueFrom— a predefined source that the platform fills in for you.
The audience claim rides only on the platform-managed token. It cannot be combined with an external identity provider (an OAuth2 tokenEndpoint) or basic authentication (type: basicAuth) — the file is rejected when you apply it. You may use it on its own or alongside scopes.
exposures:
- type: api
basePath: /checkout/v1
upstream: https://checkout.internal:8080
approval: SIMPLE
visibility: ENTERPRISE
security:
type: oauth2
claims:
aud:
valueFrom: PROVIDER_CLIENT_ID
The following sources are available for valueFrom:
| Source | Meaning | When it is filled in |
|---|---|---|
PROVIDER_CLIENT_ID | The identifier of your application (the API provider). | Automatically, by the platform. |
BASE_PATH | The base path of the exposed API. | Automatically, by the platform. |
CONSUMER_CLIENT_ID | The identifier of whichever application is calling the API. | At the moment of each request, because it is different for every consumer. |
Alternatively, you can provide a fixed value directly:
exposures:
- type: api
basePath: /checkout/v1
upstream: https://checkout.internal:8080
approval: SIMPLE
visibility: ENTERPRISE
security:
type: oauth2
claims:
aud:
value: my-checkout-audience
Audience Claim Settings
| Field | Description |
|---|---|
security.claims.aud.value | A fixed audience value that you provide. Cannot be used together with valueFrom. |
security.claims.aud.valueFrom | A predefined source the platform resolves into the audience value. One of PROVIDER_CLIENT_ID, BASE_PATH, or CONSUMER_CLIENT_ID. Cannot be used together with value. |
You must set exactly one of value or valueFrom. Setting both, or neither, is rejected when you apply the file.
Security Settings
| Field | Description |
|---|---|
security.type | The authentication method. Use oauth2 for OAuth2-based authentication or basicAuth for username/password authentication. |
security.tokenEndpoint | The OAuth2 token endpoint URL. Required when using an external identity provider. |
security.grantType | The OAuth2 grant type. Supported values: CLIENT_CREDENTIALS, PASSWORD, REFRESH_TOKEN. |
security.clientId | The OAuth2 client identifier. |
security.clientSecret | The OAuth2 client secret. Cannot be used together with clientKey. |
security.clientKey | An alternative to clientSecret for asymmetric authentication. Cannot be used together with clientSecret. |
security.refreshToken | An OAuth2 refresh token used to obtain new access tokens from the external identity provider. Used with the REFRESH_TOKEN grant type. |
security.tokenRequest | How authentication data is sent to the identity provider: body or header. On an exposure, defaults to header. On a subscription, overrides the exposure's value for the subscriber's own client credentials. |
security.username | Username for basic authentication or the OAuth2 password grant. |
security.password | Password for basic authentication or the OAuth2 password grant. |
security.scopes | A list of additional OAuth2 scopes to request. Maximum: 10 scopes. |
security.claims | Token claims written into the platform-managed token (API Exposure only). See Audience Claims. |
Secrets such as clientSecret, clientKey, refreshToken, and password are sensitive values. Do not hardcode them in your Rover files. Instead, use environment variable placeholders. Rover-CTL automatically substitutes ${VARIABLE_NAME} references with their corresponding environment variable values before sending the file to the server.
security:
type: oauth2
tokenEndpoint: https://auth.example.com/oauth/token
grantType: CLIENT_CREDENTIALS
clientId: ${MY_CLIENT_ID}
clientSecret: ${MY_CLIENT_SECRET}
Set the environment variables before applying:
export MY_CLIENT_ID="my-api-client"
export MY_CLIENT_SECRET="s3cr3t-v4lu3"
roverctl apply -f rover.yaml
If any referenced environment variable is not set, roverctl apply will fail with an error listing the unresolved variables. This ensures secrets are never accidentally left empty.
IP Restrictions
IP restrictions let you control which IP addresses or network ranges are allowed to access your application. This is configured at the Rover level, meaning it applies to all exposures and subscriptions of the application.
Applies to: Entire application (Rover-level)
apiVersion: tcp.ei.telekom.de/v1
kind: Rover
metadata:
name: checkout-service
spec:
zone: dataplane1
ipRestrictions:
allow:
- 10.0.0.0/8
- 192.168.1.100
exposures:
- type: api
basePath: /checkout/v1
upstream: https://checkout.internal:8080
approval: SIMPLE
visibility: ENTERPRISE
IP Restriction Settings
| Field | Description |
|---|---|
ipRestrictions.allow | A list of IP addresses or CIDR ranges that are allowed to access the application. Maximum: 10 entries. |
Header Removal
You can remove specific HTTP headers from incoming requests before they are forwarded to your backend service. This is useful for stripping headers that should not be passed through the gateway.
Header removal is performed by Gateway Jumper using its removeHeaders configuration, rather than by Kong's request transformer plugin.
Applies to: API Exposure
exposures:
- type: api
basePath: /checkout/v1
upstream: https://checkout.internal:8080
approval: SIMPLE
visibility: ENTERPRISE
removeHeaders:
- X-Internal-Debug
- X-Legacy-Auth
Header Removal Settings
| Field | Description |
|---|---|
removeHeaders | A list of HTTP header names to remove from incoming requests before forwarding them to the upstream service. Maximum: 5 headers. |