City

Identity

How Embassy accesses Federation user and administrator identities

Embassy Identity

Federation issues user identities and stores account data. Clients access Federation directly through Embassy. A product configures its trusted Bureau business endpoint only when it needs a backend of its own.

Identity Boundaries

  • Federation: the server runtime that issues user_token credentials and manages accounts, Services, and Bureau records.
  • Embassy User: holds the current user_token and performs user login and business requests.
  • Embassy Admin: manages Federation with an Admin Session, including authorizing Federation to issue Bureau Tokens.
  • Bureau: a product partition selected by bureau_id; its backend uses an independent Bureau client as its machine identity.

Embassy exposes only user and admin identity domains:

import { Embassy } from "@downcity/federation";

const embassy = new Embassy({
  federation_url: "https://fed.example.com",
});

Embassy is not bound to a Bureau. A login flow supplies bureau_id only when it needs a product partition.

User Identity

Account flows live under embassy.user.account. After login, the same Embassy instance starts using the new User Token immediately:

const providers = await embassy.user.account.providers();

await embassy.user.account.login({
  provider: "email",
  bureau_id: "product-web",
  input: {
    email: "[email protected]",
    password: "password",
  },
});

const current_user = await embassy.user.current();
const user_token = embassy.user.account.token();

A User Token is a JWT signed by Federation with Ed25519. It carries user_id, bureau_id, issuer, audience, and expiry claims. Public verification keys are available at:

/.well-known/downcity.json
/.well-known/jwks.json

User AI, Payment, and regular Service requests go directly to Federation:

const models = await embassy.user.ai.catalog();
const accounts = embassy.user.service("accounts");
const services = await embassy.user.list_services();

When the current Bureau has a trusted server_url, relative-path requests are sent to that origin with the current User Token. Embassy does not forward the token to another origin:

const result = await embassy.user.post(
  "/reports/summary",
  { range: "today" },
);

Administrator Identity

An administrator exchanges an ID and password for an expiring Admin Session. There is no Root Admin Token:

await embassy.admin.login({
  admin_id: "owner",
  password: "password",
});

const current_admin = await embassy.admin.current();
const bureaus = await embassy.admin.bureaus.list();

If the password is lost, an operator with deployment access resets it with fed deploy --admin-reset.

Bureau Token

An authenticated Federation Admin can issue a Bureau Token:

fed bureau token

The CLI asks Federation to generate a high-entropy token. Federation stores only its token_id, purpose, hash, and lifecycle status. The plaintext is returned once and belongs in the service environment:

DOWNCITY_FEDERATION_URL=https://fed.example.com
DOWNCITY_BUREAU_TOKEN=fb_br_xxx.secret

The business service verifies incoming Federation User Tokens through the independent Bureau client:

import { Bureau } from "@downcity/federation";

const bureau = new Bureau({
  federation_url: process.env.DOWNCITY_FEDERATION_URL!,
  bureau_token: process.env.DOWNCITY_BUREAU_TOKEN!,
});

const identity = await bureau.identify(request);

bureau_token is a long-lived, revocable opaque Bearer credential. It is not a JWT and cannot issue User Tokens. It is bound to a bureau_id when created; identify() validates the signature, issuer, audience, expiry, and that bureau_id. Revoke a leaked token immediately with fed bureau token revoke <token_id>.

Federation remains the sole User Token issuer. Account login and Admin management APIs are only entry points into Federation's issuing flow; a Bureau Token cannot call the User Token issuing API.

CredentialHolderPurposeVerification
user_tokenUser clientAccess Federation and Bureau business APIsFederation JWKS signature
admin_tokenAdministrator EmbassyFederation control planeFederation Admin Session
bureau_tokenBureau business serviceProve machine identity and call identify()Federation credential hash

Continue reading: