plan: add Vision.md (why we extract auth + success criteria)

Patrick Plate
2026-06-24 14:09:10 +02:00
parent 35d37de186
commit f1e45a066a
+161
@@ -0,0 +1,161 @@
# Vision
**Status:** Draft v1
**Date:** 2026-06-24
**Owner:** Patrick (plate-software)
---
## Elevator pitch
> **plate-auth** is the authentication, identity, and multi-tenancy layer that every plate-software product
> ships with — so we never write the same `JwtAuthenticationFilter` twice.
One library, two artifacts:
- **`de.platesoft:plate-auth-starter:0.1.x`** — a Spring Boot 4 auto-configuration starter.
Drop the dep in, configure four properties, get Google SSO + JWT + memberships + invites + access requests + admin audit.
- **`@platesoft/auth:0.1.x`** — a NextAuth v5 wiring kit for Next.js 15+ App Router.
Drop the package in, set three env vars, get the full sign-in / token exchange / proxy flow.
Together they form the canonical answer to *"how do plate-software apps do auth?"* — backed by a single Postgres
schema, a single set of JWT semantics, and a single mental model.
---
## Why we are building this
### The forcing function: Sparkboard
Sparkboard is plate-software's second product. It is greenfield, starts in Sprint 0, and must ship with the
same caliber of authentication that took InspectFlow six sub-sprints (14.1 14.6) to build.
We have two options:
1. **Copy-paste InspectFlow's auth code into Sparkboard.** Fast on day 1, painful forever — two divergent
forks of `JwtService`, two `signIn` callbacks to keep in sync, two security review surfaces, two breaking
changes whenever Spring or NextAuth ships a new major.
2. **Extract auth into a shared library.** Slower on day 1 (one extra sprint), cheaper for the rest of time.
Sparkboard's existence forces option 2. Once a second consumer exists, the maintenance cost of duplication
exceeds the cost of the abstraction.
### The strategic bet
Every plate-software product over the next five years will need:
- Sign in with a social/work identity provider (Google, Microsoft, optional email magic-link).
- Stateless server-side auth (JWT, no Spring session cookies).
- Multi-tenancy where one user can belong to many organizations with different roles.
- Invitations and access requests so admins don't manually wire every new user.
- An audit trail because some products will face regulated customers.
If we make this a library, *every product* benefits from *every security fix* and *every UX improvement*
automatically, on the next minor bump.
---
## Who consumes plate-auth
### v0.1 (Sprint 0 ship target)
| Consumer | Status | Role |
|---|---|---|
| **InspectFlow** | Existing product, refactor target | First reference consumer. Validates that extraction is non-lossy by replacing in-tree code with the library. |
| **Sparkboard** | New product, greenfield | First day-1 consumer. Validates that *integration* (not migration) is ergonomic. |
### v0.x (future plate-software apps)
Anything else we build. The library is **internal** — distributed via the plate-software Gitea Package Registry.
We are not open-sourcing it. We are not building it for external customers. The audience is "us, six months
from now, starting product #3."
---
## Non-goals
To keep v0.1 shippable, the following are explicitly **out of scope**:
| Out of scope | Why |
|---|---|
| External SSO for end-customer tenants (B2B SAML, SCIM provisioning) | No product needs it yet. Revisit in v0.4+. |
| Passwordless / WebAuthn / passkeys | Standards are stabilizing but the InspectFlow flow already has email magic-link. Add as v0.2 if a product asks. |
| OIDC server (plate-auth as identity provider for third parties) | We are an OAuth *consumer*, not a provider. Don't build this. |
| User self-service profile UI components | UI is per-product. We ship hooks and APIs, not React components. |
| Mobile native apps (iOS / Android SDKs) | Web-first. Mobile can call the same `/api/auth/exchange` endpoint and reuse the JWTs. |
| Audit log analytics / dashboards | Library emits `login_events` + Envers revisions. Visualization is a per-product concern. |
---
## What success looks like
### Sprint 0 success (ship v0.1.0)
1. ✅ A new Spring Boot 4 app can add the starter, set `plate.auth.jwt.secret` + `plate.auth.exchange.secret`
+ Google client id/secret, and have working Google SSO with JWT in under 30 minutes.
2. ✅ A new Next.js app can `npm install @platesoft/auth`, configure three env vars, and have a working
sign-in page in under 30 minutes.
3. ✅ InspectFlow's auth feature set is bit-for-bit reproducible from the library — no regression.
4. ✅ Sparkboard adopts the library on day 1 without ever seeing the InspectFlow code.
### Six-month success (post-v0.1, calibration period)
5. ✅ At least one security finding has been fixed *centrally* in plate-auth and propagated to both consumers
via a version bump (not a code-copy).
6. ✅ No consumer has needed to fork the library or shadow-override a service to ship a feature. (If they
have, the library has the wrong extension points and we fix them in v0.2.)
7. ✅ The library has shipped at least one minor version (v0.2) without breaking InspectFlow's `current`
branch — proving the SemVer policy is workable.
### Long-term success (the dream)
8. ✅ Product #3 launches with auth as a *checklist item*, not a *sub-sprint*.
9. ✅ When a CVE drops against jjwt / NextAuth / Spring Security, we patch *one* library and *all* products
are mitigated within a release cycle.
10. ✅ The decision *"how should this app do auth?"* never has to be made again.
---
## Heritage
plate-auth's design is not theoretical. It is the literal extraction of InspectFlow Sprint 14, which shipped
six sub-sprints of production-grade auth functionality:
| Sub-sprint | Codename | What it added |
|---|---|---|
| 14.1 | Octopus Camouflage | OAuth providers, JWT filter, NextAuth signIn callback, HMAC exchange envelope |
| 14.2 | Cell Membranes | Memberships decoupled from users — `Membership(user, org_type, org_id, role, status)` |
| 14.3 | Pheromone Trails | Invitations with single-use tokens, expiry, audit trail |
| 14.4 | Honeybee Quorum | Access requests with admin review, rate limiting, justification |
| 14.5 | Tardigrade Cryptobiosis | Onboarding state machine (T3 — stays in consuming apps) |
| 14.6 | Tree Rings | Admin panel, login events, Envers revision actors |
Every line of plate-auth v0.1 is code that has already shipped to production once. We are not designing —
we are *refactoring*.
---
## Trade-offs we are accepting
| Trade-off | Why we accept it |
|---|---|
| Slightly more upfront cost than copy-paste | Pays back the moment we touch auth code twice. |
| Plate-software-internal only, not open source | We do not want to support external users yet. Internal velocity > community. |
| Tight coupling to Spring Boot 4 + NextAuth v5 | These are the stacks we've committed to. Cross-framework abstraction would be over-engineering. |
| Postgres-only (Flyway migrations) | All plate-software products are Postgres. H2 is dev/test only. |
| Single tenant model per app (one user has memberships to many orgs *of the same type*) | InspectFlow has `org_type=COMPANY`, Sparkboard will define its own. Multi-org-type-per-user is theoretically supported by the schema but not exercised in v0.1. |
---
## What this document is not
- ❌ Not an architecture spec → see [`Architecture.md`](Architecture.md)
- ❌ Not a release plan → see [`Roadmap.md`](Roadmap.md)
- ❌ Not an extraction plan → see [`Sprint-0-Plan.md`](Sprint-0-Plan.md)
- ❌ Not an integration manual → see [`Integration-Guide.md`](Integration-Guide.md)
It is the **why** that the rest of the wiki points at.
---
*"Two products is a forcing function. Three products would have been a crisis. We are doing this now."*