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]