Your own users
The workspace is the operator’s console. A personal licence admits one address there, and a business licence admits several — but neither is how your users reach you.
For that you branch off a runner: a second agent, with its own engine, that serves outside callers. Through it, unlimited users authenticate for free. No per-user charge, no cap.
Two doors onto the same house
Section titled “Two doors onto the same house”A person can arrive through either, and both derive the same identity. Someone who signs in with your password today and a HexaEight Authenticator tomorrow is the same user to your application — same token, same isolation, same quota.
| BYOA — bring your own auth | alt-auth | |
|---|---|---|
| who authenticates the person | you do, exactly as you do today | the HexaEight Authenticator |
| what you build | your own frontend and backend, any auth you like | a front door against the alt-auth library |
| what your users do | nothing new | install the Authenticator (free) and type a code |
| what you keep | Clerk, Auth0, Cognito, your own password table | nothing to keep |
Neither needs a licence of its own. The only licence in play is the one your agent already has. There is no per-user cost on either door, and the Authenticator is free for everyone.
The real difference is who carries the friction: with BYOA your users notice nothing and you own the auth; with alt-auth you write almost no auth code and every user installs an app.
BYOA — keep the login you already have
Section titled “BYOA — keep the login you already have”This is the first step for most people, and it changes nothing your users can see. Your login, your user records, your sessions, your UI: untouched.
One thing changes. Instead of your backend calling a model provider with a provider key, it calls your agent and names the user:
Two consequences worth being concrete about:
- The provider key leaves your codebase. It lives in the router instead.
- Your work gets a per-user identity it can meter and isolate on, without you building one.
The agent verifies your backend. Your backend vouches for the user. That split is the whole mechanism: you are already the authority on who your users are, so nothing asks you to prove it again.
What you actually build
Section titled “What you actually build”Anything you like. A web app, a mobile app, an internal tool — with whatever login you already have.
The part that holds an identity stays on the licensed machine. That is the whole shape of BYOA, and it is worth drawing before the code:
| where it runs | what it is |
|---|---|
| your licensed machine | your identity agent, the runner branched off it, and the small caller that speaks to the runner. All three share one identity by hardlink, so this is one licence |
| anywhere you like | your front end — web app, mobile app, internal tool — with whatever login you already have. It holds no identity and needs no licence. It takes a question and hands it to the caller |
So your front end never authenticates to an agent. It collects a question, and the caller on the licensed machine runs the runner once per question, naming the user as it goes. That naming is a vouch, and it is what keeps one person’s conversation out of another’s.
That first hop is yours. How your front end reaches the caller — an HTTP call, a queue, a socket — is ordinary plumbing you write and secure yourself. HexaEight begins at the caller, where an identity exists. If your front end and the caller are on different networks, protect that hop the way you would any other internal API: it carries your users’ questions.
| an identity | only on the licensed machine: the agent, the runner and the caller, sharing one set of files |
| a separate paid licence | no, as long as the identity-holding parts sit on the machine you already licensed |
| an SDK | no. The call is made with the agent binary’s client mode — see Other software calling it |
Identity files do not travel.
env-fileandhexaeight.macare bound to the machine that activated them, and a hardlink cannot cross machines. If you were to put an identity-holding component on a second server, that server would need its own activation and therefore its own licence. Keeping the runner and its caller on the licensed machine is what avoids that, and it is the arrangement these docs describe throughout.
The caller holds nothing about your users. Your front end passes it the question and who asked, and it calls the runner:
{ "ask": "the user's question", "on_behalf_of": "<sha512 of their email>" }That is the whole integration. The runner answers; your front end renders it however you want.
No extra licence. Your backend is not separately licensed — the agent’s identity licence, which you already have, is the only one. Nothing about BYOA is charged per user.
Two things to get right:
- Name the user per request.
on_behalf_ofis what gives each person their own isolated session, so one user’s conversation never leaks into another’s. - The serving agent must be told your backend may speak for that subject. That is a vouch — see Trust and permission.
alt-auth — no password reaches you at all
Section titled “alt-auth — no password reaches you at all”The second door. A user signs in with the HexaEight Authenticator and you never handle a credential.
You still build the front end. The page has to derive a key and seal a body, so there is a reference browser client that does that part. It is not published yet — coming soon, so until it is, implement the protocol below, which is all it does.
your page POST /external/auth {email} → {session_id, challenge, expires_in: 120} the agent seals a one-time code to that address their Authenticator decrypts it and shows it they type it into your pageyour page POST /external/incoming → sealed under a key both sides derived independentlyBoth calls are made by the page in the browser, to your runner agent. What the client handles is the cryptography; you handle the two fields and the screen.
The protocol, if you are implementing it:
key = SHAKE256("hexaeight.external.v1|" + session_id + "|" + CODE) 32 bytesbody = AES-256-GCM(key, fresh 96-bit nonce) tag appendedBoth directions are sealed under the same key, so opening the reply proves the agent derived the
identical key — not merely that it accepted yours. Never reuse a nonce, and keep the key
non-extractable (crypto.subtle with extractable: false) so a script on the page cannot lift it.
The agent successfully opening the request is the authentication. There is no password to check, because there is no password.
Every alt-auth user needs the HexaEight Authenticator — it is how the code reaches them. It is free for everyone, and there is no per-user cost, but it is a real step to ask of your users. That is the trade against BYOA, where they install nothing.
What that buys, precisely:
| property | consequence |
|---|---|
| no cookies, ever | authentication is the sealed body, so there is no ambient credential a cross-site request could ride. CSRF is structurally absent, not mitigated |
| sealed both directions | opening the reply proves the agent derived the same key, not merely that it accepted yours |
| 120-second code, three attempts | an unspent code dies fast; three wrong keys end the session permanently |
| one error for “wrong key” and “no such session” | a stranger cannot probe whether a session is live |
It does not stop XSS, and nothing in a browser does. What it changes is the blast radius: a script on your page can act as the signed-in user while the tab is open — it could do that anyway by driving the page — but it cannot extract a reusable credential, because there is not one.
Letting your users in
Section titled “Letting your users in”Admit one address, or a whole domain:
# one person
# everyone at a domain — this is the one you usually wanthexaeight-activate front-door-policy allow --self --subject '*@yourcompany.com'--self says the rule is for this agent acting on behalf of the user who signed in — the
agent does the work, vouched for that person, rather than the person reaching anything directly.
--subject is who may sign in: one address, or a glob for a whole domain.
Until you add a rule, alt-auth is closed and the agent says so at startup:
[frontdoor] NO sign-in rules — alt-auth is CLOSED.Your own branding
Section titled “Your own branding”The Authenticator your users install is the HexaEight one. A white-labelled app under your own brand is possible and is an enterprise arrangement — it carries a cost, so contact support if you need it.
The agent token is a different thing. It lets a browser app authenticate to your agent, and it is created in the Authenticator under a resource — see The Authenticator. alt-auth authenticates a person. If you are letting people in, you want alt-auth.
Branching off a runner
Section titled “Branching off a runner”Both doors need an agent to arrive at, and it should not be your workspace agent. A runner is a second agent with its own ports, its own policy store, and one sealed engine — so a caller can ask it to work and cannot ask it for anything else.
hexaeight-activate add-external-agent \ --from /home/you/my-agent \ --dir /home/you/my-runner \ --mission My_Workflow \ --license personal \ --base-port 8930| flag | what it does |
|---|---|
--from | supplies the identity only — hexaeight.mac and env-file are hardlinked, never copied |
--dir | the new runner’s folder |
--mission | the one procedure this runner will serve |
--base-port | its own ports, so it can run beside your workspace agent |
It gets its own engine, sealed to that one capability:
[hexaeight-agent] engine 'missionrun-external' runs ONE mission (sealed): My_Workflow[external] enabled — authenticated:missionrun-external cleartext:OFFThat is the line that matters. If it is absent, the runner is not sealed and a caller can ask it to run whatever they like.
Why a separate agent, and not another engine on the one you have
Section titled “Why a separate agent, and not another engine on the one you have”| blast radius | the runner’s policy store is its own; admitting a customer there admits them to nothing else |
| one capability | a sealed engine serves one procedure. A caller chooses the question, never the method |
| its own ports and store | it starts, stops and is upgraded without touching your workspace |
| revocation is local | removing a customer is a rule in the runner’s store |
Read this page first, then that one. This page is about letting people in — your users, through your app. Other software calling it is about letting another system call your agent machine-to-machine, and it carries the full provisioning detail, including the parts the tool does not do for you. Both use the same runner; only the caller differs.
One thing to know before you promise it
Section titled “One thing to know before you promise it”Conversation threads do not follow a user across doors automatically. The same person arriving through BYOA and through alt-auth gets two conversations, because the thread id is minted by whoever runs the front end and the transcript is keyed on it.
If you want one thread across both doors, mint the id the same way on both — which you can, because the id is yours.