Management API
Scoped management credentials: explicit scopes, application or organization binding, product confinement, rotation with grace.
A generated OpenAPI 3.1 reference for the management API, public.
Private software infrastructure
Obsidian keeps software access under continuous server authority, from license issuance and device binding to entitlements, sessions, delivery and revocation.
Already invited? Sign in03Licensing
Products carry terms. Variants, plans, promotions, licenses and overrides layer on top, and one resolver, the same function the runtime calls, says what each holder has and why.
| Key | Product | Expires | Devices | Status |
|---|---|---|---|---|
| ATL-••••-••••-7Q2K | Pro · annual | 2027-03-02 | 1 / 2 | active |
| ATL-••••-••••-M4XA | Pro · lifetime | Lifetime | 2 / 2 | active |
| ATL-••••-••••-19HV | Team · floating | 2026-11-30 | seats 7 / 10 | active |
| ATL-••••-••••-C8RD | Pro · monthly | frozen · 21 d held | 1 / 2 | frozen |
| ATL-••••-••••-0ZLP | Pro · monthly | 2026-09-01 | 0 / 2 | expired |
04Resellers
Resellers are their own population with their own console, their own operators and their own credit ledger. What they may sell, for how long, on how many devices and with what powers is policy: set by you, narrowed by them for anyone beneath them, never widened.
05Customer identity
License key, password, magic link, Discord and passkey sign-in, per application and under your policy.
Four populations. Four cookies, four session tables, no shared door.
Operators, members, resellers and customers are separate security populations, with separate cookies, separate sessions and separate tables.
Hosted login: Authorization Code + PKCE, with license gating and refresh-token reuse detection.
06Developers
Six SDKs (JavaScript, Python, Go, Rust, C#, C++) held to one contract by one set of vectors.
npm install ./sdks/javascript # @obsidian/sdk, from the repositoryimport { ObsidianClient, DenialError } from "@obsidian/sdk";
const client = new ObsidianClient({
url: RUNTIME_ORIGIN, // https://auth.obsidian.rip
applicationId: APPLICATION_ID,
environment: "production",
publicKey: PINNED_ED25519_PUBLIC_KEY, // pinned out of band, never fetched
onState: (claims, error) => showAccessState(Boolean(claims), error?.message),
});
try {
await client.initialize({
license, // or { bridge_token } after a hosted sign-in
client_version: "1.0.0",
fingerprint,
fingerprint_version: 1,
});
client.startHeartbeats(); // every 5 s; a refusal clears client.session
const stream = client.subscribe({
onSessionEnded: (push) => console.log("ended:", push.action, push.reason),
onConfigChanged: () => reloadWhatYouCached(),
});
if (client.session?.entitlements["feature.pro"] === true) unlockPro();
} catch (e) {
if (e instanceof DenialError) show(e.code, e.reason); // reason only if signed
}Trimmed from sdks/javascript/src/index.ts; the full example is under sdks/javascript/examples and runs against the runtime in the suite where the toolchain is available.
Scoped management credentials: explicit scopes, application or organization binding, product confinement, rotation with grace.
A generated OpenAPI 3.1 reference for the management API, public.
Webhooks that are signed, retried, inspectable and replayable.
Event catch-up from an exact, gap-free sequence. No webhook required.
Live, signed notifications to running clients. The heartbeat stays the authority.
Typed remote configuration in the signed answer, with server-only values that never leave the control plane.
A CLI for the management API, credential from the environment, never an argument.
Hosted login: Authorization Code + PKCE, with license gating and refresh-token reuse detection.
07Fulfilment
From payment to permission: normalised orders, idempotent fulfilment, every step recorded and replayable.
| Step | Outcome | Detail |
|---|---|---|
| map | succeeded | variant → Pro · annual |
| customer | succeeded | found by address |
| issue | succeeded | 1 key, receipt sa_9f… |
| notify | succeeded | purchase mail, brand Atlas |
| issue (retry) | skipped | already delivered; keys read back |
Discord roles that follow licenses and entitlements, granted and removed by the platform, never by hand.
Bundles, invites and coupons that resolve to the same license rows as everything else.
Providers: SellAuth and a signed custom contract.
08Software delivery
Private object storage; five-minute authorized downloads; every grant recorded.
| Channel | Version | SHA-256 | Requires | Provenance |
|---|---|---|---|---|
| stable | 2.4.1 | e3b0…b855 | none | approved · CI |
| beta | 2.5.0-b3 | 9f86…0a08 | feature.beta | approved · staff |
| nightly | 2.5.0-n214 | 2c26…2d3d | feature.nightly | unapproved |
Watermarking identifies a leaked artifact; it is not anti-tamper.
09Migration
Discover, map, dry-run, import, verify. From an Obsidian archive, a KeyAuth export, CSV or JSON.
KeyAuth is the only named third-party format; other systems go through CSV or JSON.
10White label
Your portal, store and hosted login on your own hostname, verified by DNS, with the certificate issued at the edge.
| Hostname | Serves | DNS | Edge |
|---|---|---|---|
| portal.atlas.example | portal · brand Atlas | verified | certificate live |
| store.atlas.example | storefront → portal | verified | certificate live |
| login.atlas.example | hosted sign-in | pending TXT | waiting |
Brand name, logo, accent and support identity on every holder-facing surface.
The workspace, the reseller console and the operator console are never served on a seller's hostname. The holder-facing surfaces are, and only those.
No custom typography and no custom scripts on sign-in surfaces, by design.
Obsidian
One control plane from purchase to heartbeat. Built for sellers who have outgrown a key table.
Already invited? Sign in