plan: add Vision.md (why we extract auth + success criteria)
+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."*
|
||||||
Reference in New Issue
Block a user