temporal icon indicating copy to clipboard operation
temporal copied to clipboard

System Worker fails to authenticate after enabling JWT authorization

Open ujala-singh opened this issue 10 months ago • 2 comments

Summary

After enabling JWT authorization on Temporal cluster, system workers (like history scanner) fail to authenticate and cannot connect to the frontend service, resulting in "Request unauthorized" errors. Environment

Temporal Version: 1.24.3 Authentication Method: JWT with Keycloak/OIDC Cluster Configuration: Single frontend service with JWT authorization enabled

Problem Description

When JWT authorization is enabled on a Temporal cluster, internal system workers cannot authenticate with the frontend service and fail with authorization errors. This appears to be a common issue where system workers need authentication credentials but there's no clear documentation or configuration method to provide them.

Error Details

{
  "level": "error",
  "ts": "2025-06-03T01:04:50.770Z",
  "msg": "error starting temporal-sys-history-scanner-workflow workflow",
  "service": "worker",
  "error": "Request unauthorized.",
  "logging-call-at": "scanner.go:289",
  "stacktrace": "go.temporal.io/server/common/log.(*zapLogger).Error\n\t/home/runner/work/docker-builds/docker-builds/temporal/common/log/zap_logger.go:156\ngo.temporal.io/server/service/worker/scanner.(*Scanner).startWorkflow\n\t/home/runner/work/docker-builds/docker-builds/temporal/service/worker/scanner/scanner.go:289\ngo.temporal.io/server/service/worker/scanner.(*Scanner).startWorkflowWithRetry.func1\n\t/home/runner/work/docker-builds/docker-builds/temporal/service/worker/scanner/scanner.go:259\ngo.temporal.io/server/common/backoff.ThrottleRetryContext\n\t/home/runner/work/docker-builds/docker-builds/temporal/common/backoff/retry.go:143\ngo.temporal.io/server/service/worker/scanner.(*Scanner).startWorkflowWithRetry\n\t/home/runner/work/docker-builds/docker-builds/temporal/service/worker/scanner/scanner.go:258"
}

Current Configuration

Authorization Configuration

authorization:
  jwtKeyProvider:
    keySourceURIs:
      - https://myapp.domain.com/auth/realms/default/protocol/openid-connect/certs
    refreshInterval: "1m"
  permissionsClaimName: "permissions"
  authorizer: default
  claimMapper: default

Services Configuration

services:
    frontend:
      httpPort: 7243
      membershipPort: 6933
      port: 7233
      replicas: 2
      resources:
        limits:
          cpu: 100m
          memory: 256Mi
        requests:
          cpu: 100m
          memory: 256Mi
    history:
      httpPort: 0
      membershipPort: 6934
      port: 7234
      replicas: 2
      resources:
        limits:
          cpu: 100m
          memory: 256Mi
        requests:
          cpu: 100m
          memory: 256Mi
    matching:
      httpPort: 0
      membershipPort: 6935
      port: 7235
      replicas: 2
      resources:
        limits:
          cpu: 100m
          memory: 256Mi
        requests:
          cpu: 100m
          memory: 256Mi
    worker:
      httpPort: 0
      membershipPort: 6939
      port: 7239
      replicas: 2
      resources:
        limits:
          cpu: 100m
          memory: 256Mi
        requests:
          cpu: 100m
          memory: 256Mi

Expected Behavior

System workers should be able to operate normally when JWT authorization is enabled, either by:

Having a built-in bypass mechanism for system operations Supporting configuration of JWT credentials for system workers Clear documentation on how to configure system worker authentication

Actual Behavior

System workers fail with "Request unauthorized" errors and cannot perform essential operations like history scanning, workflow cleanup, etc.

ujala-singh avatar Jun 03 '25 08:06 ujala-singh

You'll want to use internal-frontend for the easiest integration.

It is mentioned in the release notes here: https://github.com/temporalio/temporal/releases/tag/v1.20.0 under "Internal frontend" It was introduced exactly to support this purpose.

Another option is to use mTLS but this requires integration in the claim mapper, similar to https://github.com/temporalio/samples-server/tree/main/tls/tls-full

1nu avatar Jun 03 '25 09:06 1nu

@1nu if we don't want to use mTLS for now, the only option is to use Internal frontend deployment.

internalFrontend:
   enabled: true

ujala-singh avatar Jun 04 '25 04:06 ujala-singh

Seems like this is working as intended by using an internal frontend role.

bergundy avatar Jun 26 '25 22:06 bergundy