Concepts
Security model

Security model

A community's site is run by the community, not by Cobuntu. The API is built so that whoever holds a site's keys, or controls the server those keys live on, gets no more than "act for this community, and for a signed-in member inside this community". This page lists the rules that hold that line, and what your integration has to do on its side.

Keys, sessions and limits

The rules for each credential have their own pages:

  • API keys and scopes: publishable versus secret keys, tenant binding (WRONG_COMMUNITY), expiry, and every scope.
  • Member sessions and user keys: embed sessions bound to one community, how to store them, member tokens and personal user keys.
  • Rate limits: per key, per visitor and per email, and passing the visitor's IP.

Emailed links

Sign-in links and password resets land on your site, so they are limited to people who already belong to your community:

  • Sign-in links are sent only to an accepted member or a pending applicant of this community. Anyone else gets a "create your account" email instead. The response is always 200 with the same body, so it never reveals whether an account exists.
  • Sign-in links are single-use. Exchange the token once and keep the resulting session.
  • Password resets are sent only to accepted members or pending applicants. A reset token is bound to the community that requested it: used on another community (or a token from the Cobuntu app) it is 401 INVALID_LINK, and a failed attempt does not consume it.
  • The URL these links point to (your site address) can only be set or changed by Cobuntu staff, so a compromised admin account cannot redirect members' links to another server.

Guest lookups

Lookups a browser can make on the publishable key return only what the visitor is entitled to see:

  • Attendance status. ?email= answers only registered: true | false; every other field is null, and it is limited to 10 lookups per minute per IP. For a guest's full status pass ?token=, the manage-link token from their confirmation email (lookupMode: "guest_token"). A signed-in member gets their own status through their session.
  • Member standing. members/:userId/membership follows the Members page setting and hides members who left the directory. Permissions and paid tiers are returned only to a secret key holding APP_ONBOARDING or MEMBERS_ADMIN; otherwise the fields are absent.

Applications from a browser

  • A hidden (invite-only) tier's form and submit need that tier's invitationToken. Without it the tier answers 404, the same as a tier that does not exist.
  • A publishable-key submit that would be admitted at once (free tier, open community) instead returns awaitingEmailConfirmation: true and emails the applicant a confirmation link. A secret-key submit from your server skips this, because your server vouches for the address. See Members in the REST API.

What your site must keep server-side

  • Secret keys. Any key holding MEMBER_AUTH, WRITE_MEMBERS, MEMBERS_ADMIN, ADMIN, APP_*, WRITE_SALES, WRITE_SUBSCRIPTIONS or READ_FINANCE*. Load them from environment variables in server code only.
  • Member session tokens. In an HttpOnly cookie your server reads, then client.as(token) server-side. Never send the token to the browser's JavaScript.
  • Sign-in link and reset tokens. Exchange them on the server the moment the visitor lands, then redirect to a URL without the token.
  • Authorization decisions. Re-check standing with me or members/:userId/membership on the server before granting anything privileged. Never trust a role or tier the browser tells you.