Understand Downcity City

Token Model

How administrator sessions and `user_token` work together.

Downcity uses an administrator session token to manage Federation, and user_token to let end-user clients call services.

Trusted backendYour backend logs in with an administrator ID and password, then holds a short-lived session token.Create city / request user_token
DowncityValidates the administrator session token, issues user_token, and stores provider keys internally.
End-user clientThe frontend, extension, or app uses Embassy User with user_token and calls services.No access to administrator credentials

user_token

user_token is the call credential used by the end user or product. Embassy Admin can request it from Federation using bureau_id + user_id.

  • bureau_id
  • user_id
  • metadata
  • ttl

Product configuration supplies bureau_id when login starts. After login, service calls only carry user_token; Federation reads bureau_id from the verified Token. The client never touches provider keys or administrator session tokens.

User Tokens use one downcity:user audience. Federation and Bureau Servers validate the same audience; a Bureau Server additionally compares the Token's bureau_id with its machine-bound Bureau ID. bureau_id always remains the original product-provided value and is never composed into or normalized as an audience.

Administrator session token

Use the administrator ID and password configured by fed deploy to sign in through Embassy Admin. The response contains a time-limited administrator session token for creating Bureaus, managing env, and requesting Federation to issue user_token.

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

const bureau = await embassy.admin.bureaus.create({
  name: "Chrome Extension",
  server_url: "https://bureau.example.com",
});

Multi-city reuse

Many clients can belong to the same Bureau. When issuing a token, write bureau_id explicitly:

const user = await embassy.admin.service("accounts").action("tokens/issue").invoke({
  bureau_id: bureau.bureau_id,
  user_id: "user_123",
  metadata: {
    plan: "pro",
  },
  ttl: "7d",
});

console.log(user.user_token);