You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by "Darshan-S-2002 (via GitHub)" <gi...@apache.org> on 2026/10/19 05:38:10 UTC
[D] Offline Pure JWT Guest Token: Best practices for Secret generation, storage, and BFF vs Superset responsibility [superset]
GitHub user Darshan-S-2002 created a discussion: Offline Pure JWT Guest Token: Best practices for Secret generation, storage, and BFF vs Superset responsibility
Hi Superset Community,
We are embedding Superset dashboards into an Angular portal using @superset-ui/embedded-sdk and the offline Pure JWT Guest Token approach (GUEST_TOKEN_JWT_SECRET).
Our application backend (BFF in Node.js) generates the guest tokens to enforce user-specific Row Level Security (RLS) without slow REST API calls.
We would appreciate clarification on standard best practices:
Role Division: Is it standard practice for the application backend (BFF) to mint and cryptographically sign the guest token, while Superset only acts as the verifier?
Secret Configuration: Does GUEST_TOKEN_JWT_SECRET strictly need to be configured in both the Superset instance (superset_config.py) and the application backend (BFF)?
Secret Generation: Is a 256-bit CSPRNG hex string (openssl rand -hex 32) the recommended format for this secret, and should each environment (QA, UAT, Prod) have a unique secret?
Vault Storage: In cloud deployments, is storing this secret in a vault (e.g., Azure Key Vault / AWS Secrets Manager) and injecting it into both Superset and the BFF the recommended pattern?
Thanks for your guidance!
GitHub link: https://github.com/apache/superset/discussions/45444
----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [D] Offline Pure JWT Guest Token: Best practices for Secret generation, storage, and BFF vs Superset responsibility [superset]
Posted by "FrancescoCastaldi (via GitHub)" <gi...@apache.org>.
GitHub user FrancescoCastaldi added a comment to the discussion: Offline Pure JWT Guest Token: Best practices for Secret generation, storage, and BFF vs Superset responsibility
Here is the breakdown of best practices for the offline pure JWT guest token architecture:
### 1. Role Division (BFF vs Superset)
Your proposed architecture is the recommended enterprise pattern.
- **BFF Responsibility:** Authenticates the portal user, evaluates business rules (e.g., tenant ID, region, user permissions), selects the allowed dashboard UUID, constructs Row Level Security (RLS) clauses, and signs the JWT.
- **Superset Responsibility:** Verifies the cryptographic signature against `GUEST_TOKEN_JWT_SECRET`, checks expiration (`exp`), and applies the RLS clauses to SQL queries executed on behalf of that guest session.
Never expose `GUEST_TOKEN_JWT_SECRET` to the Angular client. The browser must only receive the signed guest token via the `fetchGuestToken` callback in `@superset-ui/embedded-sdk`.
### 2. Payload Schema Distinction (`rls_rules` vs `rls`)
When calling Superset's REST endpoint (`POST /api/v1/security/guest_token/`), the JSON payload uses the key `"rls"`. However, when minting the JWT offline in your BFF, the JWT claims payload must use **`rls_rules`**.
Example Node.js BFF signing implementation:
```typescript
import jwt from 'jsonwebtoken';
function createGuestToken(user: { id: string; tenantId: string }, dashboardId: string): string {
const secret = process.env.SUPERSET_GUEST_TOKEN_SECRET!;
const payload = {
user: {
username: `guest_${user.id}`,
first_name: 'Portal',
last_name: user.id,
},
resources: [
{
type: 'dashboard',
id: dashboardId,
},
],
rls_rules: [
{
clause: `tenant_id = '${user.tenantId.replace(/'/g, "''")}'`,
},
],
type: 'guest',
aud: 'superset',
};
return jwt.sign(payload, secret, {
algorithm: 'HS256',
expiresIn: '5m', // Short TTL; SDK automatically fetches a new token before expiry
});
}
```
### 3. Secret Generation and Environment Isolation
- `openssl rand -hex 32` generates 256 bits of entropy (64 hex characters), which is optimal for HS256.
- Treat the hex string as raw text. Ensure that both Node.js (`process.env.SUPERSET_GUEST_TOKEN_SECRET`) and Superset (`GUEST_TOKEN_JWT_SECRET = os.environ.get("...")`) receive the exact same string value without decoding it into binary buffers on one side only.
- Each environment (QA, UAT, Production) must use an independent secret to prevent token forgery across tiers.
### 4. Secret Storage and Rotation
Storing the secret in Azure Key Vault or AWS Secrets Manager and injecting it as an environment variable into both the BFF and Superset containers is the standard cloud architecture. When rotating secrets, coordinate deployment to update both services simultaneously, or set a brief transition window during scheduled maintenance.
GitHub link: https://github.com/apache/superset/discussions/45444#discussioncomment-19164446
----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [D] Offline Pure JWT Guest Token: Best practices for Secret generation, storage, and BFF vs Superset responsibility [superset]
Posted by "AbdullahTammar (via GitHub)" <gi...@apache.org>.
GitHub user AbdullahTammar added a comment to the discussion: Offline Pure JWT Guest Token: Best practices for Secret generation, storage, and BFF vs Superset responsibility
Yes—direct signing in your BFF is an explicitly documented alternative in the [Embedded SDK README](https://github.com/apache/superset/tree/master/superset-embedded-sdk#creating-a-guest-token).
For the default **HS256** configuration:
- **Responsibility:** the BFF authenticates the portal user, authorizes the dashboard and RLS scope, and signs the token. Superset verifies it and enforces the resulting guest access. Never let Angular choose arbitrary dashboard IDs or RLS SQL for the BFF to sign.
- **Shared secret:** both services need the same secret bytes: Superset through `GUEST_TOKEN_JWT_SECRET`, the BFF through its signing configuration. The Angular bundle must never receive this secret. It receives only the short-lived guest token.
- **Generation:** `openssl rand -hex 32` produces 32 random bytes encoded as 64 hex characters, which is a suitable high-entropy secret for HS256. Hex is an encoding choice, not a required Superset format. If Superset uses that hex text as its secret, Node must use the same text; don't decode it with `Buffer.from(value, 'hex')` on only one side. Generate independent secrets for QA, UAT and production.
- **Storage:** a managed secret store with narrowly scoped service access is a sensible deployment pattern. Load the secret into both server processes without putting it in source control, browser configuration or logs. Coordinate rotation across both services; replacing the verification secret invalidates tokens signed with the old one.
Also match `GUEST_TOKEN_JWT_ALGO` and `GUEST_TOKEN_JWT_AUDIENCE`. The direct JWT uses **`rls_rules`**, whereas the guest-token issuance API accepts **`rls`**. Follow the documented claims, including `type: "guest"`, `resources`, `user`, `iat`, `exp` and `aud`. Set a short lifetime explicitly in the BFF: Superset's `GUEST_TOKEN_JWT_EXP_SECONDS` controls its own issuer, not the expiration your BFF writes.
The current [configuration](https://github.com/apache/superset/blob/master/superset/config.py) and [security manager](https://github.com/apache/superset/blob/master/superset/security/manager.py) show the signing/verification settings. Check them against your deployed release, especially if you enable additional guest-token validation or revocation settings.
*AI-generated; checked against the linked official documentation and source, not tested against your deployment.*
GitHub link: https://github.com/apache/superset/discussions/45444#discussioncomment-19034655
----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org