Skip to content

Authentication

See Security & Auth Overview and JWT Flow for the full authentication lifecycle. This page focuses on the backend implementation details.

Every protected request passes through:

Request → [Logger] → [Recovery] → [Auth] → [RBAC] → [Handler]

Auth middleware (Backend/internal/middleware/auth.go):

  • Extracts JWT from Authorization: Bearer <token>
  • Validates signature and expiry (HS256, SECRET_KEY)
  • Sets tenant_id and user_id in the Fiber context

RBAC middleware (Backend/internal/middleware/rbac.go):

  • Reads required permission from the route definition
  • Loads user’s group memberships from DB (or short-lived in-memory cache)
  • Returns 403 Forbidden if the resolved permission set doesn’t include the required permission
Env varDefaultPurpose
SECRET_KEYrequiredHMAC signing key for JWT (≥32 chars in production)
ACCESS_TOKEN_EXPIRE_MINUTES60Access token TTL
REFRESH_TOKEN_EXPIRE_DAYS7Refresh token TTL
MFA_ISSUERMonozuCloudTOTP issuer shown in authenticator apps

Auth domain (Backend/internal/domain/auth/)

Section titled “Auth domain (Backend/internal/domain/auth/)”

Key files:

FileResponsibility
handler.goHTTP handlers for all /api/v1/auth/* endpoints
service.goBusiness logic: token issuance, TOTP verification, OIDC exchange
repository.goUser lookup, refresh token storage, invitation management

TOTP is optional and configurable per tenant. When enabled:

  1. POST /api/v1/auth/login returns { mfa_required: true, session_token: "..." } instead of JWTs
  2. User enters the TOTP code from their authenticator app
  3. POST /api/v1/auth/mfa/verify with { totp_code, session_token } issues the JWT pair

The TOTP secret is generated with github.com/pquerna/otp/totp and stored encrypted in the database.

The Entra ID flow is handled in Backend/internal/domain/auth/handler.go:

  • GET /api/v1/auth/microsoft/login — builds and redirects to the Entra authorization URL
  • GET /api/v1/auth/microsoft/callback — exchanges the code, extracts the ID token, finds or creates the user, issues JWT pair, redirects to the SPA

See SSO & Entra ID for configuration and flow details.

Controlled by AUTH_POLICY env var:

// standard: all login methods allowed
// restricted: Entra ID SSO only

Under restricted, the following endpoints return 403:

  • POST /api/v1/auth/login
  • POST /api/v1/auth/register
  • POST /api/v1/auth/check-method

The user’s email domain is validated against AUTH_ALLOWED_EMAIL_DOMAINS after OIDC token exchange.

Cross-origin cookie delivery requires:

ALLOW_ORIGINS=https://cloud.monozu.io # comma-separated SPA URLs
REFRESH_COOKIE_SAMESITE=none # cross-origin: none; same-site: strict (default)

The SameSite=None cookie attribute requires HTTPS. In local dev, strict works when both SPA and API are on localhost.