Skip to content
Unified Defense StackUnified Defense Stack

Protect applications with Authservice

You’ll configure operator-managed Authservice protection for an application. Authservice handles the browser OIDC flow at the Istio mesh boundary, validates requests before they reach the application, and requires users to log in through Keycloak before accessing the protected workload. This pattern can be preferable even when an application supports native OIDC because it keeps authentication enforcement outside the application.

  • UDS Core deployed (Authservice is included by default)
  • UDS CLI installed
  • Application deployed as a UDS Package
  • Application pods labeled with a consistent selector that you control

Authservice works by matching a label selector on your application’s pods. When a request comes in, Authservice intercepts it, validates the session, and redirects unauthenticated users to Keycloak. The UDS Operator creates the Authservice chain and the required Istio resources automatically. The first redirectUris entry you configure populates the match.prefix hostname and the callback_uri in the Authservice chain.

Authservice forwards the authenticated OIDC ID token to the application, while Istio preserves an inbound bearer token when one is already present. Use groups.anyOf to control which users can reach the workload. After access is granted, application code can use the forwarded identity and, when configured, groups claims for fine-grained authorization. See Register and customize SSO clients for the group membership mapper. Istio and Authservice also provide platform-level telemetry.

  1. Add enableAuthserviceSelector to the Package CR

    Set the selector to match the labels on your application pods:

    package.yaml
    apiVersion: uds.dev/v1alpha1
    kind: Package
    metadata:
    name: httpbin
    namespace: httpbin
    spec:
    sso:
    - name: Demo SSO httpbin
    clientId: uds-core-httpbin
    redirectUris:
    - "https://httpbin.uds.dev/login"
    enableAuthserviceSelector:
    app: httpbin

    Authservice will protect all pods labeled app: httpbin in the httpbin namespace.

  2. Apply the Package CR

    Terminal window
    uds zarf tools kubectl apply -f package.yaml

    The UDS Operator creates a Keycloak client, configures Authservice, and sets up the Istio RequestAuthentication and AuthorizationPolicy resources automatically.

Confirm the generated Istio policies and Authservice chain:

Terminal window
# Check that Authservice pods are running
uds zarf tools kubectl get pods -n authservice -l app.kubernetes.io/name=authservice
# Check the generated Istio policies for your app
uds zarf tools kubectl get authorizationpolicy -n <app-namespace>
uds zarf tools kubectl get requestauthentication -n <app-namespace>
# Linux: inspect the Authservice chain in its managed Secret
uds zarf tools kubectl get secret authservice-uds -n authservice \
-o jsonpath='{.data.config\.json}' | base64 -d | jq '.chains[] | select(.name == "<client-id>")'
# macOS: use base64 -D instead of base64 -d
uds zarf tools kubectl get secret authservice-uds -n authservice \
-o jsonpath='{.data.config\.json}' | base64 -D | jq '.chains[] | select(.name == "<client-id>")'

The Istio policies confirm JWT and Authservice enforcement. The Secret check confirms that the matching Authservice chain exists for the client.

End-to-end test:

  1. Open the application URL in a browser
  2. You should be redirected to the Keycloak login page
  3. Log in with valid credentials
  4. You should be redirected back to the application and see the content

Problem: Package CR is rejected with a redirect URI error

Section titled “Problem: Package CR is rejected with a redirect URI error”

Symptoms: kubectl apply fails with an error about invalid redirect URIs.

Solution: The redirect URI must not be a root path. Replace root-path URIs with a specific path:

# Invalid: root path not allowed for Authservice clients
redirectUris:
- "https://myapp.example.com/"
# Valid
redirectUris:
- "https://myapp.example.com/login"

Problem: Traffic is blocked with 503 errors in ambient mode

Section titled “Problem: Traffic is blocked with 503 errors in ambient mode”

Symptoms: After applying the Package CR with ambient mode, requests to the application return 503.

Solution: Verify that the enableAuthserviceSelector matches both the pod labels AND the spec.selector of the Kubernetes Service for those pods. If the selector matches pod labels but not the service selector, the waypoint proxy is associated with the pods but not the service, so traffic through the service is blocked rather than routed through the SSO flow.

Terminal window
# Compare pod labels with service selector
uds zarf tools kubectl get pods -n <app-namespace> --show-labels
uds zarf tools kubectl get service -n <app-namespace> -o yaml | grep -A5 selector

Problem: Prometheus cannot scrape metrics from a protected pod

Section titled “Problem: Prometheus cannot scrape metrics from a protected pod”

Symptoms: Prometheus shows scrape errors for a workload that uses enableAuthserviceSelector.

Solution: The monitor[].podSelector (or monitor[].selector) in the Package CR must include the labels from the protected workload’s sso[].enableAuthserviceSelector. The monitor selector may include additional labels. When the selectors match, the operator creates an authorization exception that allows Prometheus to scrape metrics directly without going through the SSO flow.

spec:
monitor:
- selector:
app: httpbin # Must include the enableAuthserviceSelector labels
portName: metrics
targetPort: 9090
sso:
- name: Demo SSO
clientId: uds-core-httpbin
redirectUris:
- "https://httpbin.uds.dev/login"
enableAuthserviceSelector:
app: httpbin # Selects the protected application pods