{
"host": "app.demo.localhost", "path": "/*", "frontend": true,
"backend": "http://127.0.0.1:8080", "auth": {},
"inject": "bundle.json",
"userBadge": {
"position": "right",
"claims": ["preferred_username", "email"],
"roles": ["admin"],
"logoutLabel": "Sign out"
},
"uiGate": [
{ "selector": ".danger-zone", "roles": ["admin"] },
{ "selector": ".beta-feature", "hidden": "before" },
{ "selector": "[data-feature=export]", "auth": "before" }
],
"authGuard": { "forbidden": { "banner": true } },
"csp": { "mode": "nonce" },
"pwa": {
"enabled": true,
"networkOnly": {
"excludePatterns": [
"^https://idp\\.example\\.com/.*/\\.well-known/openid-configuration",
"^https://idp\\.example\\.com/.*/protocol/openid-connect"
]
}
}
}Injectable UX
This example runs with the dev provider and demonstrates every
injection surface in one route.
Route
Bundle
{
"injects": [
{
"name": "announcement", "target": "body-end",
"when": "/dashboard", "file": "banner.html"
},
{
"name": "brand-style", "target": "head",
"style": ".demo-brand{letter-spacing:.02em}"
}
],
"patch": [{
"selector": "[data-feature=beta]",
"attrs": { "data-gtw-auth-hidden": "before" }
}]
}injects[].when targets a path prefix; file is read at load, relative
to the bundle. patch appends the data-gtw-* attributes client-side on
every guard evaluation.
Try it
The packaged demo serves the gated dashboard and starts Gate One (no Docker):
cd gate-one-src/deploy/local/injectable-ux
BIN_DIR=~/gate-one-bin ./run.shThe script prints the URLs and stops with ./run.sh down. See [deploy/local/injectable-ux](https://github.com/clad-one/gate-one/tree/main/deploy/local/injectable-ux) for the stack and its README.
To run it by hand instead:
python3 -m http.server 8080
gate-one -check -config routes.json
gate-one -config routes.jsonLog in as alice (user) then bob (admin). The .danger-zone is only
visible to admin; the .beta-feature is hidden before login; the export
control opens a login tab and replays the action after login.
CSP
csp.mode: "nonce" emits Gate One’s own policy and stamps inline
scripts. If the application already sends a CSP, prefer
csp.mode: "merge"; if the application forbids inline scripts, use
hash or merge and keep application scripts external.
PWA and identity endpoints
pwa.enabled wraps the route in a service worker that caches same-origin
pages and assets. Any URL that carries identity must therefore be
excluded with pwa.networkOnly.excludePatterns (JS regexes tested
against the full URL). Otherwise the worker can serve a cached auth
probe — a stale identity after login or logout — or replay a callback
that carries a one-time code.
Always exclude:
the identity provider’s discovery, authorize, token, JWKS and end-session endpoints;
any token endpoint used by API or machine clients (OAuth/JWT), and the
http-bridgelogin URL when the route uses that provider;the Gate One callback (
/auth/callback) and, with the embedded IAM,/t/<tenant>/callback, which carrycode/state.
"pwa": {
"enabled": true,
"networkOnly": {
"excludePatterns": [
"^https://idp\\.example\\.com/.*/\\.well-known/openid-configuration",
"^https://idp\\.example\\.com/.*/protocol/openid-connect",
"^https://idp\\.example\\.com/.*/end_session_endpoint",
"^http://login\\.demo\\.localhost:3000/auth/callback",
"^http://login\\.demo\\.localhost:3000/t/[^/?#]+/callback"
]
}
}Replace idp.example.com with the issuer host. See the
routes.pwa.networkOnly
reference.
Note |
|