Skip to content

Conversation

@nataliasitko
Copy link
Contributor

Description

Changes proposed in this pull request:

  • Improve the JWT tutorial

Pre-Merge Checklist

Consider all the following items. If your contribution violates any of them, or you are not sure about it, add a comment to the PR.

  • The code coverage is acceptable.
  • Release notes for the introduced changes are created.
  • If Kubebuilder changes were made, you ran make generate-manifests and committed the changes before the merge.
  • Pre-existing managed resources are correctly handled.
  • The change works on all hyperscalers supported by SAP BTP, Kyma runtime.
  • There is no upgrade downtime.
  • For infrastructure changes, you checked if the changes affect the hyperscaler's costs.
  • RBAC settings are as restrictive as possible.
  • If any new libraries are added, you verified license compliance and maintainability, and made a comment in the PR with details. We only allow stable releases to be included in the project.
  • You checked if this change should be cherry-picked to active release branches.
  • The configuration does not introduce any additional latency.

Related issues

@nataliasitko nataliasitko requested a review from a team as a code owner November 4, 2025 07:48
@kasiakepka kasiakepka requested a review from a team November 5, 2025 08:25
@joanbod joanbod self-requested a review November 5, 2025 12:41
---------|----------|---------
**PARENT_DOMAIN** | `my-own-domain.example.com` | The domain name available in the public DNS zone.
**SUBDOMAIN** | `mtls.my-own-domain.example.com` | A subdomain created under the parent domain, specifically for the mTLS Gateway.
**GATEWAY_DOMAIN** | `*.mtls.my-own-domain.example.com` | A wildcard domain covering all possible subdomains under the mTLS subdomain. When configuring the Gateway, this allows you to expose workloads on multiple hosts (for example, `httpbin.mtls.my-own-domain.example.com`, `test.httpbin.mtls.my-own-domain.example.com`) without creating separate Gateway rules for each one.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably we should change every metnion of mtls to tls?


If the validation is successful, the request proceeds to the Service behind the Gateway. At that point you can implement optional, deeper authorization (examining scopes, audience, or custom claims) inside your application code.

## Configure a TLS Gateway for Your Custom Domain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea that maybe after each step (or most of the steps) for Custom Domain set up there should be check if this resource user have created is in state ready or doesn't have any errors? like in case with secret we ask user to check if it created

```
<!-- tabs:end -->
See the following example of a sample HTTPBin Deployment exposed by an APIRule with JWT authentication:
```yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want the user to apply this sample deployment? or just let the user browse how this sample deployment could look like?

@@ -0,0 +1,364 @@
# Expose and Secure a Workload with JWT Using SAP Cloud Identity Services

This guide explains how to expose a workload on a custom domain secure it with JSON Web Tokens (JWT) issued by SAP Cloud Identity Services using the Client Credentials grant.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This guide explains how to expose a workload on a custom domain secure it with JSON Web Tokens (JWT) issued by SAP Cloud Identity Services using the Client Credentials grant.
This guide explains how to expose a workload on a custom domain and secure it with JSON Web Tokens (JWT) issued by SAP Cloud Identity Services using the Client Credentials grant.

Do you think we need an "s" in the abbreviation? JWTs?


## Prerequisites

- You have a SAP BTP, Kyma runtime instance with the Istio and API Gateway modules added. The Istio and API Gateway modules are added to your Kyma cluster by default.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- You have a SAP BTP, Kyma runtime instance with the Istio and API Gateway modules added. The Istio and API Gateway modules are added to your Kyma cluster by default.
- You have an SAP BTP, Kyma runtime instance with the Istio and API Gateway modules added. The Istio and API Gateway modules are added to your Kyma cluster by default.

- You have an SAP Cloud Identity Services tenant. See [Initial Setup](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/initial-setup?locale=en-US&version=Cloud&q=open+id+connect).

## Context
Use this procedure to secure your workload with a short living JWT. To get the JWT, you must first register an OpenID Connect (OIDC) application in SAP Cloud Identity Services and enable the Client Credentials grant. This generates a client ID (public identifier) and a client secret (confidential credential). A calling system sends these credentials to the OIDC token endpoint over TLS, receiving a signed JWT access token.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use this procedure to secure your workload with a short living JWT. To get the JWT, you must first register an OpenID Connect (OIDC) application in SAP Cloud Identity Services and enable the Client Credentials grant. This generates a client ID (public identifier) and a client secret (confidential credential). A calling system sends these credentials to the OIDC token endpoint over TLS, receiving a signed JWT access token.
Use this procedure to secure your workload with a short-lived JWT. To get the JWT, you must first register an OpenID Connect (OIDC) application in SAP Cloud Identity Services and enable the Client Credentials grant. This generates a client ID (public identifier) and a client secret (confidential credential). A calling system sends these credentials to the OIDC token endpoint over TLS, receiving a signed JWT.

JWT already includes the work "token", so maybe "a signed JWT" would be sufficient?

@@ -0,0 +1,364 @@
# Expose and Secure a Workload with JWT Using SAP Cloud Identity Services
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Expose and Secure a Workload with JWT Using SAP Cloud Identity Services
# Expose and Secure a Workload with a JWT Using SAP Cloud Identity Services

If it means "JSON Web Token," then maybe we need an article?


When the client calls your exposed API, it includes the token in the Authorization header using the Bearer scheme. The API Gateway module validates the token based on the configuration you include in the APIRule custom resource (CR). If the validation fails, the Gateway returns `HTTP/2 403 RBAC: access denied` without forwarding the request to the backend Service.

If the validation is successful, the request proceeds to the Service behind the Gateway. At that point you can implement optional, deeper authorization (examining scopes, audience, or custom claims) inside your application code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If the validation is successful, the request proceeds to the Service behind the Gateway. At that point you can implement optional, deeper authorization (examining scopes, audience, or custom claims) inside your application code.
If the validation is successful, the request proceeds to the Service behind the Gateway. At that point, you can implement optional, deeper authorization (examining scopes, audience, or custom claims) inside your application code.

3. Choose the OpenID API access and provide other configuration as needed.
For more configuration options, see [Configure Secrets for API Authentication](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/dev-configure-secrets-for-api-authentication?version=Cloud&locale=en-US).
4. Choose **Save**.
Your client ID and secret appear in a pop up window. Save the secret as you will not be able to retrieve it from the system later.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Your client ID and secret appear in a pop up window. Save the secret as you will not be able to retrieve it from the system later.
Your client ID and secret appear in a pop-up window. Save the secret, as you will not be able to retrieve it from the system later.

4. Choose **Save**.
Your client ID and secret appear in a pop up window. Save the secret as you will not be able to retrieve it from the system later.

### Get a JWT Token
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JWT already included the word Token.

Suggested change
### Get a JWT Token
### Get a JWT

```bash
export ENCODED_CREDENTIALS=$(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64)
```
3. Get **token_endpoint**, **jwks_uri**, issuer from your OpenID application, and save these values as environment variables:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Get **token_endpoint**, **jwks_uri**, issuer from your OpenID application, and save these values as environment variables:
3. Get **token_endpoint**, **jwks_uri**, and the issuer from your OpenID application, and save these values as environment variables:

port: 8000
```

1. To test the connection, first do not provide the JWT token.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. To test the connection, first do not provide the JWT token.
1. To test the connection, first, do not provide the JWT.

4. Choose **Create**.

#### **kubectl**
To expose and secure your Service, create the APIRule custom resource. In the rules section define the **jwt** field and specify the issuer and jwksUri.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To expose and secure your Service, create the APIRule custom resource. In the rules section define the **jwt** field and specify the issuer and jwksUri.
To expose and secure your Service, create the APIRule custom resource. In the rules section, define the **jwt** field and specify the **issuer** and **jwksUri**.

not sure, but these also seem to be parameters?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants