aicam opened a new issue, #4397:
URL: https://github.com/apache/texera/issues/4397

   ### What happened?
   
   ## Summary
   
   The Texera Helm chart did not expose `AUTH_JWT_SECRET` as an overridable
   environment variable, and the `access-control-service` deployment did not
   propagate the shared `texeraEnvVars` block. As a result, a fresh
   `helm install` silently fell back to a hard-coded JWT signing secret,
   and the access-control service could not verify tokens signed with any
   value an operator did override elsewhere.
   
   ## Affected components
   
   - Helm chart: `bin/k8s/values.yaml`
   - Helm chart: `bin/k8s/templates/access-control-service-deployment.yaml`
   - JWT configuration: `common/config/src/main/resources/auth.conf`
   - JWT loading: 
`common/config/src/main/scala/org/apache/texera/config/AuthConfig.scala`
   - JWT signing/verification: 
`common/auth/src/main/scala/org/apache/texera/auth/JwtAuth.scala`
   
   ## Background
   
   Texera signs user authentication tokens with HMAC-SHA256. The signing
   key is read from `auth.conf`:
   
   ```hocon
   auth {
       jwt {
           256-bit-secret = "8a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d"
           256-bit-secret = ${?AUTH_JWT_SECRET}
       }
   }
   ```
   
   The `${?AUTH_JWT_SECRET}` override only takes effect when the
   environment variable is set at container startup. `AuthConfig.scala`
   reads this value once and hands it to `JwtAuth.scala`, which uses it
   both to mint new tokens (`jwtToken`) and to verify incoming ones
   (`jwtConsumer`). Every service that mounts `auth.conf` must therefore
   agree on the same secret, or tokens minted by one service will be
   rejected by another.
   
   ## The problem
   
   Two gaps made the Helm deployment insecure and inconsistent.
   
   ### 1. No `AUTH_JWT_SECRET` entry in `values.yaml`
   
   `bin/k8s/values.yaml` defines a `texeraEnvVars` list that is rendered
   into every Texera service deployment. Before this PR the list did not
   contain `AUTH_JWT_SECRET`, so:
   
   - Operators running `helm install` with defaults never set the secret.
   - The JVM fell back to the placeholder string committed in `auth.conf`.
   - That placeholder is public in the repository and is shared across
     every default install of Texera. Anyone who knows the default can
     forge tokens for any user on any deployment that did not manually
     override the variable.
   
   The fix adds an explicit placeholder entry to force operators to
   override it in production, and to document the requirement in the
   chart itself:
   
   ```yaml
   - name: AUTH_JWT_SECRET
     # PLACEHOLDER: must be >=32 chars (256 bits) for HS256. Override in 
production.
     value: "REPLACE_ME_WITH_A_RANDOM_32B_PLACEHOLDER_SECRET"
   ```
   
   ### 2. `access-control-service` did not receive `texeraEnvVars`
   
   `bin/k8s/templates/access-control-service-deployment.yaml` only wired
   in a handful of service-specific variables (JDBC URL and password,
   compute pool name/namespace) and did not iterate over
   `texeraEnvVars`. The access-control service is one of the components
   that verifies JWTs — it needs the same `AUTH_JWT_SECRET` that the
   token-minting services use. Without the shared block, the service
   either fell back to the hard-coded default in `auth.conf` or (if
   other services were overridden out-of-band) failed to validate
   otherwise-valid tokens.
   
   The fix appends the shared block to the deployment's `env:` list:
   
   ```yaml
   {{- range .Values.texeraEnvVars }}
   - name: {{ .name }}
     value: "{{ .value }}"
   {{- end }}
   ```
   
   This guarantees that the access-control service sees the same
   `AUTH_JWT_SECRET` (and any other shared variable) as the rest of the
   stack.
   
   ## Impact
   
   - **Security:** Default Helm installs signed tokens with a publicly
     known secret. An attacker who can reach the API could forge a JWT
     for any user, including privileged roles, bypassing authentication.
   - **Correctness:** Any operator who overrode the secret for the
     token-minting services without also overriding it for the
     access-control service would see authenticated requests rejected
     as the signatures did not match.
   
   ## Resolution (PR #4388)
   
   - Add `AUTH_JWT_SECRET` with an obvious placeholder to
     `texeraEnvVars` in `bin/k8s/values.yaml` so the variable is visible
     and operators are prompted to override it.
   - Propagate `texeraEnvVars` into the `access-control-service`
     deployment template so the secret (and all other shared env vars)
     reach every service that needs them.
   
   ## Operator guidance
   
   After upgrading the chart, override the placeholder before deploying:
   
   ```bash
   helm upgrade --install texera ./bin/k8s \
     --set-string 'texeraEnvVars[N].name=AUTH_JWT_SECRET' \
     --set-string 'texeraEnvVars[N].value=<32+ random bytes>'
   ```
   
   or provide a values override file that replaces the placeholder with a
   secret of at least 32 characters (256 bits), e.g. `openssl rand -hex 32`.
   Deployments that keep the placeholder string should be treated as
   insecure.
   
   ## Verification
   
   - Local Helm install with the placeholder overridden: all services
     (including `access-control-service`) start, mint tokens, and
     validate them against each other.
   - Production deployment: same behavior confirmed end-to-end.
   
   
   ### How to reproduce?
   
   Checkout `main` before #4388 and generate token for user id 1 using default 
key in auth.conf and login to the system and upload files.
   
   ### Version
   
   1.1.0-incubating (Pre-release/Master)
   
   ### Commit Hash (Optional)
   
   _No response_
   
   ### What browsers are you seeing the problem on?
   
   _No response_
   
   ### Relevant log output
   
   ```shell
   
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to