Security

Authentication, credentials, token lifecycle, and session management — SecurityService, JWT token versioning, OAuth2, passkeys, and API tokens.

Overview

Bosca's security layer is built around Principals (user accounts) and Credentials (authentication methods). A single Principal can have multiple credentials — password, OAuth2, API tokens, and WebAuthn passkeys — all managed through the SecurityService.

Principal

The core identity record. Every authenticated user is a Principal.

kotlin
tokenVersion is central to session security — every JWT includes a tver claim that must match the Principal's current version, or the token is rejected.

Credential Types

Credentials are polymorphic — each type stores its data in a JSON attributes field on PrincipalCredential.

TypeStorageNotes
PASSWORDArgon2 hashPrimary login method
PASSWORD_SCRYPTScrypt hashLegacy support — migrated on next login
OAUTH2Provider tokenGoogle, Facebook, Apple
API_TOKENSHA-256 hashScoped tokens with group restrictions
PASSKEYWebAuthn public keyFIDO2 with sign-count anti-cloning

Authentication Flows

Password Login

graphql

Returns a short-lived JWT (token) and a long-lived refreshToken. The refresh token is single-use — exchanging it atomically deletes the old one and issues a new pair.

OAuth2 / Third-Party

Supports GOOGLE, FACEBOOK, and APPLE. The client obtains a provider token and exchanges it via the signupThirdParty or loginThirdParty mutations. Bosca validates the token with the provider and creates or links the credential.

Passkeys (WebAuthn)

FIDO2/WebAuthn passkeys for passwordless authentication. The server tracks the signCount to detect cloned authenticators.

API Tokens

Long-lived tokens for programmatic access. Each token has optional scopes and allowed groups to restrict what it can do. The raw token is shown once at creation; only the SHA-256 hash is stored.

Token Versioning

Every JWT includes a tver (token version) claim. The Principal's tokenVersion is a monotonic counter that increments on security-sensitive events:

  • Password change
  • Identifier (email) change
  • Credential deletion
  • Explicit logout (all sessions)

When tver in the JWT doesn't match the current tokenVersion, the token is rejected — effectively invalidating all outstanding sessions without maintaining a token blacklist.

Groups & Roles

Groups are the foundation of authorization. Every Group carries a GroupType:

GroupTypePurpose
SYSTEMBuilt-in roles (SA, admin, editor, manager) plus user-defined groups for team/project access control
PRINCIPALAuto-created per user, used for personal entity permissions
See the Permissions page for how groups interact with PermissionEvaluator to control entity access.

SecurityService

The central interface for all authentication and credential management:

kotlin

Email Verification

New accounts can optionally require email verification. A verificationToken is generated on signup and sent via email. The verify mutation validates the token and marks the Principal as verified.

Password Reset

The forgot-password flow generates a time-limited reset token sent via email. The resetPassword mutation validates the token, updates the password hash, and bumps tokenVersion to invalidate all existing sessions.