Smart Agent Teams

Account

Sign-up, sign-in, sessions, password reset, your profile and your preferences.

Your account is how SAT knows who you are. It holds your email, name, password, avatar and preferences, and it is what every company membership, approval decision and activity entry points back to. Accounts are personal: companies are separate, and one account can belong to several companies.

How it works

Register

You register with an email, a name and a password; an optional company text field is stored but not used. Registering signs you in immediately (the response carries tokens). The email must not already be registered (409 USER_EXISTS).

RuleServer (POST /api/register)Web app form
Password length8 to 128 charactersAt least 8 characters
Name1 to 255 charactersRequired for sign-up
EmailValid email addressValid email address

The web app then sends you to Start your company to create your first company.

Sign in and lockout

POST /api/login checks the email (an exact match on the stored address) and password and returns an access token and a refresh token.

  • After 5 failed attempts in a row the account is locked for 30 minutes. The fifth failure still answers 401 INVALID_CREDENTIALS; attempts during the lock answer 400 ACCOUNT_LOCKED, even with the right password.
  • A successful sign-in, or completing a password reset, resets the counter and clears the lock.
  • Once a lock has expired, the counter starts again from zero: it takes another five wrong passwords to lock the account again.
  • A deactivated account answers 400 ACCOUNT_INACTIVE.

Sign in with Google

When the API has a Google OAuth client ID (GOOGLE_OAUTH_CLIENT_ID), the sign-in page shows Sign in with Google. The web app reads the client ID at runtime from GET /api/auth/config, so switching it on or off needs no rebuild.

  • The button uses Google Identity Services in a popup and returns a Google ID token. The web app posts it to POST /api/login/google, which verifies the signature, the audience (your client ID), the issuer and the expiry.
  • Only an email address Google has verified (email_verified) is accepted. That is what makes it safe to link by email: a Google sign-in for grace@example.com opens the existing SAT account with that address (matched without regard to case), or creates one on first use.
  • A new account gets your Google name and picture and no usable password. Set one later with Forgot password? if you also want password sign-in.
  • A Google sign-in clears any lockout from failed password attempts and starts a normal session (the same access and refresh tokens as a password sign-in).
  • Failures answer 401 GOOGLE_SIGN_IN_FAILED; when the feature is off the endpoint answers 404 GOOGLE_DISABLED. It is rate limited to 10 requests a minute per IP address.

Setting up a client. Create one OAuth client per environment in the Google Cloud project that hosts that environment (Google Auth Platform, Clients, type Web application). Add the web app's origins under Authorized JavaScript origins, for example https://sat.example.com and http://localhost:4200 for local development. No redirect URI and no client secret are needed. Then set GOOGLE_OAUTH_CLIENT_ID on the API (Configuration). While the consent screen is in Testing, only its listed test users can sign in.

Sessions

TokenLifetimeNotes
Access token (JWT)30 minutesSent as Authorization: Bearer … on every request.
Refresh token7 daysStored hashed on the server. POST /api/refresh returns a new access token only; the refresh token is not rotated and keeps working until it expires or is revoked.

Each sign-in (each browser, each CLI profile) creates its own refresh token, so sessions are independent. The web app and CLI refresh the access token automatically.

Sign out

POST /api/logout revokes refresh tokens:

  • With refresh_token in the body: only that session ends. The web app's Sign out and sat logout do this.
  • Without it: every session you have ends, in every browser and CLI profile. sat logout --everywhere does this.

Signing out needs a session: a request authenticated with an API key gets 403 SESSION_REQUIRED. Access tokens that were already issued stay valid until they expire (up to 30 minutes). API keys are not affected by signing out; revoke them separately.

Password reset

Select Forgot password? on the sign-in form, or call POST /api/password/forgot with your email. The answer is always the same ("If an account exists for that email, we've sent a link…"), so it does not reveal who is registered. The email match ignores case.

Open the email

The email "Reset your Smart Agent Teams password" links to /reset-password?token=… on the web app. The link works once and expires after 30 minutes. Asking for a new link voids older ones. You can ask at most once a minute per account, and at most 5 times a minute per IP address.

Choose a new password

Enter a password of 8 to 128 characters. Completing the reset signs you out everywhere: every refresh token is revoked, access tokens issued before the change stop working, and API keys created before the change stop working too. It also clears any lockout. Then sign in with the new password.

Email is sent over SMTP, configured with SMTP_HOST, SMTP_PORT (default 587, STARTTLS), SMTP_SECURE=true for implicit TLS, SMTP_USER, SMTP_PASSWORD and MAIL_FROM. Without SMTP settings no email is sent: outside production the message (with the link) is written to the API log so you can test locally; in production only a warning is logged. See Configuration.

Profile

PATCH /api/me changes your name (trimmed; it cannot be empty) and avatar URL (an https:// link of at most 500 characters; null removes it). Only the fields you send change. Your email cannot be changed.

Preferences

Preferences are one document on your account, so they follow you to every device. PATCH /api/me/preferences merges a partial update: objects merge key by key, lists replace the stored list, and an explicit null removes a setting (back to the app's default). Unknown keys are rejected with 422 VALIDATION_ERROR. GET /api/me returns the current document as preferences.

Prop

Type

How the web app uses them is described in Views and preferences.

API keys

For runners, CI and scripts, create a personal API key (sat_live_…) instead of storing your password. Keys are created with a signed-in session, shown once, optionally expire after 1 to 3650 days, and are revoked individually. A password reset ends every key created before it, so create new keys for your runners afterwards. See Authentication.

Fields

GET /api/me and PATCH /api/me return UserResponse:

Prop

Type

Use it

  • Sign up / sign in at /login (or from the homepage). The form switches between Sign in and Sign up.
  • Forgot password? opens /forgot-password; the email link opens /reset-password.
  • Settings → Profile: change your name, picture URL and avatar colour.
  • Settings → Appearance & region: theme, density, accent, language and region, time zone and date format.
  • Sign out is in the account menu at the bottom of the sidebar. It ends this browser's session only.

Permissions

You can only read and change your own account. There are no endpoints to list users, change another user, or deactivate an account. Creating or revoking an API key, and signing out, need a session token; an API key gets 403 SESSION_REQUIRED.

Events

Account changes publish no live events and write no company activity entries. A profile or preference change made on one device reaches your other devices the next time they load /api/me.

Limits and known gaps

  • Sign-in matches the email exactly as stored, while password reset ignores case. If you registered as Ada@NoteFlow.dev, sign in with that capitalisation.
  • Signing out does not invalidate access tokens already issued; they work for up to 30 minutes.
  • Refresh tokens are not rotated on use.
  • The lockout message differs from the invalid-credentials message, which reveals that an account exists.
  • No email verification, no change of email, no account deletion, no two-factor authentication and no single sign-on.
  • The company field at registration and the currency preference are stored but unused.

On this page