Files
ss-tools/specs/016-multi-user-auth/research.md
2026-01-27 13:26:06 +03:00

3.5 KiB

Research: Multi-User Authentication and Authorization

1. Authentication Strategy

Decision: Hybrid Local + ADFS (OIDC)

We will implement a dual authentication strategy:

  1. Local Auth: Username/Password stored in auth.db with bcrypt hashing.
  2. ADFS: OpenID Connect (OIDC) integration for enterprise SSO.

Rationale:

  • Local Auth: Ensures the system is usable without external dependencies (ADFS) and provides a fallback for admins.
  • ADFS: Requirement for corporate environment integration. OIDC is the modern standard supported by ADFS 2016+.
  • Just-In-Time (JIT): ADFS users will be provisioned locally upon first successful login if they belong to a mapped AD group.

Alternatives Considered:

  • SAML 2.0: Older protocol, more complex to implement (XML-based) than OIDC. Rejected in favor of OIDC/OAuth2 support in Authlib.
  • LDAP Direct Bind: Requires handling credentials directly, less secure than token-based SSO.

2. Session Management

Decision: Stateless JWT (JSON Web Tokens)

Sessions will be managed using signed JWTs containing sub (user_id), exp (expiration), and scopes (roles).

Rationale:

  • Stateless: No need to query the DB for every request to validate session validity (signature check is fast).
  • Scalable: Works well with load balancers (though not a primary concern for this scale).
  • Frontend Friendly: Easy to parse in JS to get user info without an extra API call.

Security Measures:

  • Short-lived Access Tokens (e.g., 15-30 min).
  • HttpOnly Cookies for storage to prevent XSS theft.
  • Refresh Token rotation (stored in DB) for long-lived sessions.

3. Authorization Model

Decision: RBAC (Role-Based Access Control)

Permissions are assigned to Roles. Users are assigned one or more Roles.

Structure:

  • Permissions: Granular capabilities (e.g., plugin:backup:execute, plugin:migration:read).
  • Roles: Collections of permissions (e.g., Admin, Operator, Viewer).
  • Users: Assigned to Roles.

Rationale:

  • Standard industry practice.
  • Simplifies management: Admin assigns a role to a user rather than 50 individual permissions.
  • AD Group Mapping fits naturally: AD_Group_X -> Role_Y.

4. Persistence

Decision: Dedicated SQLite Database (auth.db)

A separate SQLite database file for authentication data.

Rationale:

  • Separation of Concerns: Keeps auth data distinct from task history or other app data.
  • Relational Integrity: Enforces foreign keys between Users, Roles, and Permissions better than JSON.
  • Concurrency: SQLite WAL mode handles concurrent reads/writes better than a single JSON config file.

Schema Draft:

  • users (id, username, password_hash, is_active, auth_source)
  • roles (id, name, description)
  • permissions (id, resource, action)
  • role_permissions (role_id, permission_id)
  • user_roles (user_id, role_id)
  • ad_group_mappings (ad_group_name, role_id)

5. Frontend Integration

Decision: SvelteKit Stores + HttpOnly Cookies

Authentication state will be synchronized between the server (cookies) and client (Svelte store).

Mechanism:

  • Login endpoint sets access_token cookie (HttpOnly).
  • Client makes API calls; browser automatically sends cookie.
  • hooks.server.ts (or similar middleware) validates token on server-side rendering.
  • Client-side store ($auth) holds user profile (decoded from token or fetched via /me endpoint) for UI logic (show/hide buttons).