Embedding security¶
- Embed tokens required — never pass
jrs_PATs to the browser SDK. - ACL still applies — token minting and
/embed/*both enforce Report Server permissions. - Allowed origins — set
ACUGIS_EMBED_ALLOWED_ORIGINS(comma-separated). Only those origins may frame/embed/*(Content-Security-Policy: frame-ancestors). - Normal UI stays protected — non-embed routes keep
X-Frame-Options: SAMEORIGIN. - postMessage — host and viewer validate origin, source window, protocol
source: "acugis-report", andversion: 1. Production code never usespostMessage(..., "*"). - No secrets in URLs long-term —
et=bootstraps the embed; the viewer strips it after setting an HttpOnly embed cookie. - Bound parameters — host-owned values such as
account_idbelong inPOST /api/v1/embed/tokenparameters, minted by the host backend with a PAT. Report Server overwrites the browser value on execute and on report data endpoints. Hiding the control is not the security boundary. See Parameters.
Server configuration¶
Native installs (Debian package and install.sh) write the signing secret to /etc/acugis-report-server/env:
- A fresh installation generates a 32-byte hex secret with
openssl rand -hex 32(or Pythonsecrets.token_hex) on that machine. It is not hard-coded and is not the same on every installation. - The env file is mode
640, ownerroot, groupwww-data, which is the same file systemd reads asEnvironmentFile. The Go server and PHP helpers also fall back to that path. The secret is not written toinitial-credentials, is not copied to/opt/acugis-report-server/.env, and is not printed by the installer. An older copy in that.envis removed on upgrade. - Package upgrades do not replace the env file and do not rotate a secret that is already set.
- If
ACUGIS_EMBED_TOKEN_SECRETorJRS_EMBED_TOKEN_SECRETis already in the env file, that value is kept. If neither key is set, an administrator value supplied in the environment at configure time is written. Otherwise a new secret is generated. - Set
ACUGIS_EMBED_ALLOWED_ORIGINSto the host pages that may frame reports. That allow-list is not generated for you.
ACUGIS_EMBED_ALLOWED_ORIGINS=https://app.example.com,https://portal.example.com
ACUGIS_EMBED_TOKEN_SECRET=long-random-secret
ACUGIS_EMBED_TOKEN_TTL=15m
Docker Compose still expects ACUGIS_EMBED_TOKEN_SECRET in the compose .env file. Development and test processes use a fixed fallback secret when the variable is unset. Production does not.
Development defaults add common localhost origins when the allow-list is empty.