# JWT Secret Management

This directory contains secure configuration for JWT secret key management.

## Files

- `jwt-secret.yaml`: Kubernetes Secret + ServiceAccount + RBAC rules
- `ENCRYPTION.md`: Guide for enabling ETCD static encryption at rest

## Quick Start

### 1. Create the Secret and RBAC

```bash
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
```

This will create:
- Secret `jwt-secret` in namespace `juwan` containing the JWT secret key
- ServiceAccount `user-rpc` in namespace `juwan`
- ServiceAccount `envoy-gateway` in namespace `juwan`
- Role `jwt-secret-reader` that allows reading only `jwt-secret`
- RoleBindings to grant both ServiceAccounts read permission on the secret

### 2. Update user-rpc Deployment

Update `deploy/k8s/service/user/user-rpc.yaml` to:

1. Set the serviceAccountName:
```yaml
spec:
  template:
    spec:
      serviceAccountName: user-rpc
```

2. Add environment variable to load JWT secret:
```yaml
spec:
  template:
    spec:
      containers:
      - name: user-rpc
        env:
        - name: JWT_SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: jwt-secret
              key: secret-key
```

### 3. Update envoy-gateway Deployment

Update `deploy/k8s/envoy/envoy.yaml` to:

1. Set the serviceAccountName:
```yaml
spec:
  template:
    spec:
      serviceAccountName: envoy-gateway
```

2. Add environment variable or mount Secret:
```yaml
volumeMounts:
- name: jwt-secret
  mountPath: /etc/jwt
  readOnly: true

volumes:
- name: jwt-secret
  secret:
    secretName: jwt-secret
    defaultMode: 0400
```

Then reference it in the Envoy config:
```yaml
data:
  envoy.yaml: |
    # Read JWT secret from /etc/jwt/secret-key
```

### 4. Enable ETCD Encryption

Follow the guide in `ENCRYPTION.md` to enable static encryption at rest for all secrets in ETCD.

## Security Considerations

### Least Privilege

- Only `user-rpc` and `envoy-gateway` can read the JWT secret
- No other services or users have access
- The Role allows reading **only** the `jwt-secret`, not other secrets

### Encryption at Rest

- With ETCD encryption enabled, the secret is encrypted when stored on disk
- Even if someone gains access to the ETCD database files, they cannot read the secret without the encryption key

### Secret Rotation

To rotate the JWT secret key:

1. Generate a new key
2. Update the Secret:
   ```bash
   kubectl create secret generic jwt-secret --from-literal=secret-key=NEW_KEY --dry-run=client -o yaml | kubectl apply -f -
   ```
3. Pod mounts/env vars will be updated automatically within a few minutes
4. Old tokens will become invalid (you may need to log users out)

## Production Checklist

- [ ] ETCD encryption enabled (see ENCRYPTION.md)
- [ ] JWT secret key changed from default
- [ ] Both user-rpc and envoy-gateway Deployments use correct serviceAccountName
- [ ] Both Deployments load the secret via environment variable or volume mount
- [ ] Regular secret rotation policy implemented
- [ ] Secret backup stored in secure location (encrypted)
- [ ] RBAC audit logging enabled to track secret access

## Troubleshooting

### Cannot read jwt-secret
Check if the Pod is using the correct ServiceAccount:
```bash
kubectl get deployment user-rpc -o yaml | grep serviceAccountName
```

### Secret not being mounted
Verify the Secret exists:
```bash
kubectl get secret jwt-secret -n juwan
```

Check Pod logs for mounting errors:
```bash
kubectl logs -l app=user-rpc -n juwan
```

### Permission denied error
Verify RBAC binding:
```bash
kubectl get rolebinding -n juwan
kubectl get role jwt-secret-reader -n juwan
```
