You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Direction changed (2026-07-21). Reworked from a standalone "sup build with a pasted ACM key" into an ACM extension: same-origin, cookie-authenticated, opened in a new browser tab. This dissolves the control-plane-key security model entirely (see "Out of scope / dissolved"). Original design + the review that prompted this pivot are in the comments.
Goal
Extend ACM's existing simple SQL editor (acm-ui → cluster-explore/query) with the full Altinity SQL Browser, for the support team. The SQL Browser is served same-origin under acm.altinity.cloud and opened in a new tab from a link in the ACM console (cluster/explore page). It authenticates via ACM's existing HttpOnly session cookie — no token, no login form, no pasted key.
Why this shape
Same-origin ⇒ cookie auth "just works". A JS fetch('/api/…', {credentials:'same-origin'}) inherits ACM's session (verified live: GET /api/account returns 200 with no auth header). Nothing is stored in JS; XSS can't read an HttpOnly cookie.
Authorization + audit are ACM's job (server-side, per the account's role/rights). Our app enforces nothing — it calls the API and surfaces 403s.
Least coupling. No iframe, no web component, no Angular changes beyond a link. Our repo stays a standalone single-file SPA, delivered as a static asset into ACM's docroot.
Verified API contract
(See the probe-transcript comment — still valid.) POST /api/cluster/{id}/query accepts a JSON body, is cookie-authed, and returns a per-node array [{node,label,result,meta{queryId,error},summary}]; result is a string (the raw CH text for the requested FORMAT); errors are signalled by meta.error, never HTTP status. acm-ui's own cluster-explore/query already consumes this exact shape and already manages support-credential mint/refresh (/support/credentials, /support/refresh).
Deployment model (from the acm repo)
acm-ui is ng build'd and its dist/ is baked into the altinity/acm image docroot /var/www/html/, alongside the PHP /api (symlinked). We add our built sql.html to that same docroot. Two constraints found in the vhost:
FallbackResource /index.html (Angular SPA catch-all) → serve our app as a real file at a concrete path (e.g. /sql/index.html), not a virtual route, so Apache serves it directly.
Strict page CSP — ACM's page CSP has no 'unsafe-inline'/'unsafe-eval' for scripts; our single-inline-<script> bundle would be blocked. Fix with a scoped <Location /sql/> CSP block (precedent: /api/, /signup already have their own) — the /api/ CSP ('self' 'unsafe-inline' 'unsafe-eval' *.gstatic.com data:) is exactly what we need. (Alternative: a CSP-friendly build emitting external JS from 'self' with no inline/eval.)
Three-repo change set
Repo
Change
Issue
altinity-sql-browser
Cookie-auth ChCtx/transport variant; read cluster/node from URL; transport adapter; {name:Type} render (or consume server-forwarded params)
Goal
Extend ACM's existing simple SQL editor (
acm-ui→cluster-explore/query) with the full Altinity SQL Browser, for the support team. The SQL Browser is served same-origin underacm.altinity.cloudand opened in a new tab from a link in the ACM console (cluster/explore page). It authenticates via ACM's existing HttpOnly session cookie — no token, no login form, no pasted key.Why this shape
fetch('/api/…', {credentials:'same-origin'})inherits ACM's session (verified live:GET /api/accountreturns 200 with no auth header). Nothing is stored in JS; XSS can't read an HttpOnly cookie.Verified API contract
(See the probe-transcript comment — still valid.)
POST /api/cluster/{id}/queryaccepts a JSON body, is cookie-authed, and returns a per-node array[{node,label,result,meta{queryId,error},summary}];resultis a string (the raw CH text for the requested FORMAT); errors are signalled bymeta.error, never HTTP status. acm-ui's owncluster-explore/queryalready consumes this exact shape and already manages support-credential mint/refresh (/support/credentials,/support/refresh).Deployment model (from the
acmrepo)acm-ui is
ng build'd and itsdist/is baked into thealtinity/acmimage docroot/var/www/html/, alongside the PHP/api(symlinked). We add our builtsql.htmlto that same docroot. Two constraints found in the vhost:FallbackResource /index.html(Angular SPA catch-all) → serve our app as a real file at a concrete path (e.g./sql/index.html), not a virtual route, so Apache serves it directly.'unsafe-inline'/'unsafe-eval'for scripts; our single-inline-<script>bundle would be blocked. Fix with a scoped<Location /sql/>CSP block (precedent:/api/,/signupalready have their own) — the/api/CSP ('self' 'unsafe-inline' 'unsafe-eval' *.gstatic.com data:) is exactly what we need. (Alternative: a CSP-friendly build emitting external JS from'self'with no inline/eval.)Three-repo change set
ChCtx/transport variant; readcluster/nodefrom URL; transport adapter;{name:Type}render (or consume server-forwarded params)<Location /sql/>CSP block/sql/?cluster=…&node=…(new tab)Connection lifecycle
/sql/?cluster=<id>&node=<n>(cluster/node from ACM console context — no URL-resolution guessing).GET /api/account(cookie) → engineer email (CHuser=attribution).GET /api/cluster/{id}/support/credentials(cookie) → temp CH pass; keep alive via/support/refreshor re-mint.POST /api/cluster/{id}/query(cookie, JSON body, explicitnode)./query-kill/actionKillProcesses(best-effort; see [sup] Best-effort cancel via /query-kill; remove streaming; export + session-script limits #356).Transport constraints (proven; unchanged by the auth reframe)
param_*not forwarded →{name:Type}client-side render, or (preferred, given tight integration) an ACM-side ask to forward a structured param/settings map ([sup] Parameters: forward natively server-side, else strict {name:Type} renderer + parity test #355).SETTINGS(verified effective) ([sup] ACM-mode transport adapter: cookie auth, JSON-body /query, per-format result unwrap, settings-into-SQL, fake-stream #353).SETscripts unsupported (declared limitation).Out of scope / dissolved by this model
#usersentinel; Chrome-password-store handling; key-in-localStorage/share-link/export leakage; scoped-role token issuance; per-cluster entitlement enforcement; audit/consent/approval flows. All handled by ACM server-side or made impossible by cookie-only auth. The security review ([sup] Security review (reduced): no-token-in-JS, transport escaping, CSP, token rotation #358) shrinks accordingly.Sub-issues
#353 transport adapter · #354 cookie-auth session + URL context + temp-cred lifecycle · #355
{name:Type}render / ACM param-forward · #356 cancel + remove streaming + export/session limits · #357 same-origin deployment (acm/acm-ui) · #358 (reduced) security review.