Files
Ignas Baranauskas a72711697d chore: remove deprecated --keep flag from docs, scripts, and e2e tests (#2126)
* docs: remove deprecated --keep flag from tutorials and examples

The --keep flag is deprecated, hidden, and a no-op since sandboxes
are kept by default. Remove references from tutorial docs and example
READMEs that explain it as a real feature.

- Remove --keep from sandbox create commands
- Remove --keep explanation text
- Clarify that sandboxes are kept by default

Signed-off-by: Ignas Baranauskas <ibaranau@redhat.com>

* chore: remove deprecated --keep usage from scripts and e2e tests

The --keep flag is a deprecated no-op since sandboxes are kept by
default. Stop passing it in internal scripts, e2e test scripts,
and example demo scripts.

Signed-off-by: Ignas Baranauskas <ibaranau@redhat.com>

---------

Signed-off-by: Ignas Baranauskas <ibaranau@redhat.com>
2026-07-07 14:36:25 +02:00
..

SPIFFE Token Grant Demo

This example validates provider dynamic token grants using SPIFFE JWT-SVIDs. It mirrors the PR 1781 alpha/beta flow without configuring OpenShell gateway OIDC authentication.

The demo deploys three in-cluster workloads:

Workload Purpose
token-issuer Accepts a SPIFFE JWT-SVID client assertion and returns a short-lived demo access token
alpha Requires a bearer token with audience and scope alpha
beta Requires a bearer token with audience and scope beta

The OpenShell provider profile in provider-profile.yaml configures a dynamic credential with token_grant. When a sandbox curls alpha or beta, the sandbox supervisor fetches a JWT-SVID from the SPIFFE Workload API, exchanges it at token-issuer, and injects the returned access token into the outbound HTTP request.

Prerequisites

  • A Kubernetes OpenShell dev cluster.
  • SPIRE enabled for provider token grants.
  • OpenShell configured with the Kubernetes ServiceAccount supervisor bootstrap path. Gateway end-user OIDC is not required for this demo.
  • providers_v2_enabled=true on the target gateway.

For the Helm dev environment, deploy with the SPIRE releases and ci/values-spire.yaml enabled in deploy/helm/openshell/skaffold.yaml.

Deploy Workloads

From the repository root:

ACCESS_TOKEN_SECRET="$(openssl rand -hex 32)"
KUBECONFIG=kubeconfig kubectl -n default create secret generic openshell-spiffe-token-demo \
  --from-literal=access-token-secret="$ACCESS_TOKEN_SECRET" \
  --dry-run=client \
  -o yaml | KUBECONFIG=kubeconfig kubectl apply -f -
KUBECONFIG=kubeconfig kubectl apply -k examples/spiffe-token-grant-demo/k8s
KUBECONFIG=kubeconfig kubectl -n default rollout restart deployment/token-issuer deployment/alpha deployment/beta
KUBECONFIG=kubeconfig kubectl -n default rollout status deployment/token-issuer --timeout=180s
KUBECONFIG=kubeconfig kubectl -n default rollout status deployment/alpha --timeout=180s
KUBECONFIG=kubeconfig kubectl -n default rollout status deployment/beta --timeout=180s

Register Provider And Test

Port-forward the local gateway in one terminal:

KUBECONFIG=kubeconfig kubectl port-forward -n openshell svc/openshell 8097:8080

Then run:

export XDG_CONFIG_HOME="$(mktemp -d)"
export GATEWAY=http://127.0.0.1:8097

openshell --gateway-endpoint "$GATEWAY" settings set \
  --global --key providers_v2_enabled --value true --yes

openshell --gateway-endpoint "$GATEWAY" provider profile import \
  -f examples/spiffe-token-grant-demo/provider-profile.yaml

openshell --gateway-endpoint "$GATEWAY" provider create \
  --name spiffe-token-demo \
  --type spiffe-token-demo \
  --runtime-credentials

openshell --gateway-endpoint "$GATEWAY" sandbox create \
  --name spiffe-token-demo \
  --provider spiffe-token-demo \
  --no-tty \
  -- echo "sandbox ready"

openshell --gateway-endpoint "$GATEWAY" sandbox exec \
  --name spiffe-token-demo \
  --no-tty \
  -- curl -sS http://alpha.default.svc.cluster.local/

openshell --gateway-endpoint "$GATEWAY" sandbox exec \
  --name spiffe-token-demo \
  --no-tty \
  -- curl -sS http://beta.default.svc.cluster.local/

Expected output includes endpoint-specific token claims:

alpha called with path /:
  aud: alpha, account
  scope: alpha profile email
  azp: spiffe://openshell.local/openshell/sandbox/<sandbox-id>

beta called with path /:
  aud: beta, account
  scope: beta profile email
  azp: spiffe://openshell.local/openshell/sandbox/<sandbox-id>

The protected services also write proof-of-life logs when they accept a call:

KUBECONFIG=kubeconfig kubectl -n default logs deployment/alpha --tail=20
KUBECONFIG=kubeconfig kubectl -n default logs deployment/beta --tail=20

Example log lines:

alpha accepted request path=/ aud="alpha, account" scope="alpha profile email" client_id=spiffe://openshell.local/openshell/sandbox/<sandbox-id>
beta accepted request path=/ aud="beta, account" scope="beta profile email" client_id=spiffe://openshell.local/openshell/sandbox/<sandbox-id>

Automated Demo

demo.sh applies the workloads, registers the provider profile, creates a sandbox, curls alpha and beta, prints the alpha/beta pod logs, and deletes the sandbox with openshell on exit. It leaves the Kubernetes demo workloads in place.

KUBECONFIG=kubeconfig bash examples/spiffe-token-grant-demo/demo.sh

Cleanup

Delete the sandbox through OpenShell:

openshell --gateway-endpoint "$GATEWAY" sandbox delete spiffe-token-demo

Delete the demo workloads with Kubernetes:

KUBECONFIG=kubeconfig kubectl delete -k examples/spiffe-token-grant-demo/k8s