Signing up on Subako Cloud
Creating an organization from a browser, through the Service API.
Subako Cloud has a second API beside the one SubakoClient reaches. The Service API creates organizations: someone signs in at Subako Cloud’s identity provider, and the ID token that sign-in ends in creates an organization with them invited as its admin. An on-premises deployment runs no Service API, so none of this applies there.
SubakoServiceClient reaches it. The sign-in is the OAuth 2.0 authorization code grant with PKCE, relayed by the Service API, so the page that starts it never holds a client secret:
import { createCodeChallenge, SubakoServiceClient } from "@subako-ai/sdk";
const service = new SubakoServiceClient();
const redirectUri = "https://console.example.com/signup/callback";
// 1. Before the browser leaves: keep the verifier and a fresh state, then go.
const { verifier, challenge } = await createCodeChallenge();
const state = crypto.randomUUID();
sessionStorage.setItem("signup", JSON.stringify({ verifier, state }));
const { authorization_url } = await service.auth.authorize({
redirect_uri: redirectUri,
state,
code_challenge: challenge,
});
location.assign(authorization_url);
The identity provider sends the browser back to redirect_uri with code and state. Check the state is the one you sent, then redeem the code with the verifier:
// 2. On the callback page.
const params = new URLSearchParams(location.search);
const kept = JSON.parse(sessionStorage.getItem("signup") ?? "{}");
if (params.get("state") !== kept.state) throw new Error("the sign-in came back for another request");
const { id_token, email } = await service.auth.exchangeCode({
code: params.get("code") ?? "",
code_verifier: kept.verifier,
redirect_uri: redirectUri,
});
// 3. Create the organization as the person who signed in.
const signedUp = new SubakoServiceClient({ idToken: id_token });
const organization = await signedUp.organizations.create({ handle: "acme", name: "Acme Corp" });
// organization.invited_email === email: they sign in to it as that account.
A deployment takes its sign-ups through one redirect URI, its console’s callback, and refuses any other with an InvalidRequestError. A deployment that takes no sign-up from a browser answers ForbiddenError. A repeated create with the same ID token answers with the organization as it stands rather than a second one.
SubakoServiceClient defaults to https://service.us.cloud.subako.ai. It takes the same baseUrl, fetch, headers, timeout and maxRetries as the other clients, and retries the same way. Without an idToken it sends no Authorization header, which is what the sign-in calls need and what a proxy attaching its own credential expects.