@rineex/auth-core 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Definition.md ADDED
@@ -0,0 +1,1490 @@
1
+ ## Step 1 — Define **Auth Method SPI (Plugin Contract)**
2
+
3
+ This is the **most critical step**. If this is wrong, everything after becomes
4
+ rigid.
5
+
6
+ ---
7
+
8
+ # Auth Method SPI — Domain-Level Contract
9
+
10
+ ## 1. Goal of This Step
11
+
12
+ Define **how authentication methods plug into the core** without:
13
+
14
+ - Modifying domain logic
15
+ - Adding conditionals (`if password`, `if oauth`)
16
+ - Leaking protocol / provider / infra concerns
17
+ - Forcing storage or transport choices
18
+
19
+ This SPI must support:
20
+
21
+ - Password
22
+ - Passwordless
23
+ - OTP
24
+ - OAuth / OIDC
25
+ - Social login
26
+ - Future methods (passkeys, DID, etc.)
27
+
28
+ ---
29
+
30
+ ## 2. What an Auth Method IS (and is NOT)
31
+
32
+ ### ✅ IS
33
+
34
+ - A **capability descriptor**
35
+ - A **set of required inputs**
36
+ - A **type of proof produced**
37
+ - A **participant in a flow**
38
+
39
+ ### ❌ IS NOT
40
+
41
+ - A service with business logic
42
+ - A protocol implementation
43
+ - A provider SDK wrapper
44
+ - A controller or handler
45
+ - A persistence concern
46
+
47
+ If logic creeps in here → stop.
48
+
49
+ ---
50
+
51
+ ## 3. Core Domain Abstractions
52
+
53
+ ### 3.1 AuthMethodType (Value Object)
54
+
55
+ Represents **identity**, not behavior.
56
+
57
+ ```ts
58
+ AuthMethodType
59
+ - value: string
60
+ ```
61
+
62
+ Rules:
63
+
64
+ - Stable identifier
65
+ - Configurable
66
+ - No enums hardcoded in domain
67
+
68
+ Examples:
69
+
70
+ - `password`
71
+ - `passwordless_email`
72
+ - `otp_totp`
73
+ - `oauth_oidc`
74
+ - `social_google`
75
+
76
+ ---
77
+
78
+ ### 3.2 AuthMethodDefinition (Domain Object)
79
+
80
+ This is the **plugin contract**.
81
+
82
+ ```ts
83
+ AuthMethodDefinition
84
+ - type: AuthMethodType
85
+ - supportedFactors: Set<AuthFactorType>
86
+ - requiredInputs: Set<AuthInputType>
87
+ - outputProof: AuthProofType
88
+ - challengeCapable: boolean
89
+ ```
90
+
91
+ This object:
92
+
93
+ - Is immutable
94
+ - Is registered at startup
95
+ - Contains **no logic**
96
+
97
+ ---
98
+
99
+ ## 4. Auth Inputs (What the method needs)
100
+
101
+ Auth methods declare **what they need**, not _how it arrives_.
102
+
103
+ ```ts
104
+ AuthInputType -
105
+ identifier -
106
+ secret -
107
+ otp -
108
+ assertion -
109
+ authorization_code -
110
+ device_context -
111
+ redirect_context;
112
+ ```
113
+
114
+ Rules:
115
+
116
+ - Transport-agnostic
117
+ - Serializable
118
+ - Validated at boundaries
119
+
120
+ ---
121
+
122
+ ## 5. Auth Proof (What the method produces)
123
+
124
+ Auth methods **do not authenticate**. They produce **proof**.
125
+
126
+ ```ts
127
+ AuthProofType - password_proof - otp_proof - oauth_proof - assertion_proof;
128
+ ```
129
+
130
+ The **domain decides** what to do with the proof.
131
+
132
+ ---
133
+
134
+ ## 6. Verification Responsibility (Important)
135
+
136
+ Auth Methods **do not verify themselves**.
137
+
138
+ Verification is done via **ports**:
139
+
140
+ ```ts
141
+ AuthProofVerifierPort
142
+ - verify(proof, context): VerificationResult
143
+ ```
144
+
145
+ This allows:
146
+
147
+ - Swapping providers
148
+ - Mocking
149
+ - Enterprise overrides
150
+ - Multiple verification strategies
151
+
152
+ ---
153
+
154
+ ## 7. Method Registration Model
155
+
156
+ Auth methods are **registered**, not hardcoded.
157
+
158
+ ```ts
159
+ AuthMethodRegistry - register(definition) - get(type) - list();
160
+ ```
161
+
162
+ Rules:
163
+
164
+ - Registry is read-only at runtime
165
+ - Domain depends only on interface
166
+ - Infrastructure provides implementations
167
+
168
+ ---
169
+
170
+ ## 8. Example (Conceptual, Not Implementation)
171
+
172
+ | Method | Inputs | Proof | Factor |
173
+ | ---------- | ------------------- | --------------- | ---------- |
174
+ | Password | identifier + secret | password_proof | knowledge |
175
+ | Magic Link | identifier | assertion_proof | possession |
176
+ | OTP | identifier + otp | otp_proof | possession |
177
+ | OAuth | authorization_code | oauth_proof | delegated |
178
+ | API Token | token | assertion_proof | possession |
179
+
180
+ Notice:
181
+
182
+ - No HTTP
183
+ - No redirects
184
+ - No JWT
185
+ - No providers
186
+
187
+ ---
188
+
189
+ ## 9. What This Enables
190
+
191
+ With this SPI, you can:
192
+
193
+ - Add a new auth method **without touching domain logic**
194
+ - Compose methods into MFA
195
+ - Enable / disable methods via config
196
+ - Support enterprise overrides
197
+ - Keep core stable for years
198
+
199
+ ---
200
+
201
+ ## 10. Hard Validation Checklist
202
+
203
+ Before moving forward, confirm:
204
+
205
+ - No logic inside method definitions
206
+ - No branching by method type
207
+ - No enum explosion
208
+ - No provider coupling
209
+ - No storage assumptions
210
+
211
+ If any fails → redesign now.
212
+
213
+ ---
214
+
215
+ ## Step 1 Status
216
+
217
+ ✅ Auth Method SPI defined ✅ Extensible ✅ Domain-pure ✅ Hexagonal-safe
218
+
219
+ ---
220
+
221
+ # Step 2 — Authentication Flow DSL (Orchestration Model)
222
+
223
+ This step defines **how authentication happens**, without:
224
+
225
+ - Hard-coding flows
226
+ - Coupling to methods
227
+ - Assuming HTTP redirects
228
+ - Embedding logic in code paths
229
+
230
+ If flows are not modeled explicitly, you will **never** support enterprise auth
231
+ cleanly.
232
+
233
+ ---
234
+
235
+ ## 1. Purpose of Authentication Flow
236
+
237
+ An **Authentication Flow** answers one question:
238
+
239
+ > _“In what order, under what conditions, and with which rules are auth methods
240
+ > executed?”_
241
+
242
+ It must support:
243
+
244
+ - Single-step auth (password, social)
245
+ - Multi-step auth (OTP, MFA)
246
+ - Conditional auth (risk-based)
247
+ - Enterprise SSO
248
+ - Future orchestration (passkeys, step-up)
249
+
250
+ ---
251
+
252
+ ## 2. Core Principle (Non-Negotiable)
253
+
254
+ **Flows are data, not code.**
255
+
256
+ No:
257
+
258
+ ```ts
259
+ if (method === 'password') { ... }
260
+ ```
261
+
262
+ Instead:
263
+
264
+ - Declarative steps
265
+ - Explicit transitions
266
+ - Policy-driven decisions
267
+
268
+ ---
269
+
270
+ ## 3. Flow as a Domain Concept
271
+
272
+ ### AuthenticationFlow (Domain Object)
273
+
274
+ ```ts
275
+ AuthenticationFlow
276
+ - flowId
277
+ - name
278
+ - steps: AuthFlowStep[]
279
+ - entryConditions
280
+ - exitConditions
281
+ ```
282
+
283
+ Rules:
284
+
285
+ - Immutable
286
+ - Versionable
287
+ - Serializable
288
+ - Loaded at startup or via config
289
+
290
+ ---
291
+
292
+ ## 4. Flow Step Model
293
+
294
+ ### AuthFlowStep
295
+
296
+ ```ts
297
+ AuthFlowStep
298
+ - stepId
299
+ - authMethodType
300
+ - required: boolean
301
+ - onSuccess: Transition
302
+ - onFailure: Transition
303
+ - onChallenge?: Transition
304
+ ```
305
+
306
+ Each step:
307
+
308
+ - Executes **exactly one Auth Method**
309
+ - Produces a proof
310
+ - Does NOT decide success globally
311
+
312
+ ---
313
+
314
+ ## 5. Transition Model
315
+
316
+ ### Transition
317
+
318
+ ```ts
319
+ Transition
320
+ - targetStepId | terminalState
321
+ - condition?: PolicyExpression
322
+ ```
323
+
324
+ Terminal states:
325
+
326
+ - `AUTHENTICATED`
327
+ - `FAILED`
328
+ - `CHALLENGED`
329
+
330
+ This enables:
331
+
332
+ - Retry
333
+ - Step-up
334
+ - Short-circuiting
335
+
336
+ ---
337
+
338
+ ## 6. Policy Expressions (Referenced, Not Implemented Yet)
339
+
340
+ Flows do **not** evaluate logic themselves.
341
+
342
+ They reference policies:
343
+
344
+ ```ts
345
+ PolicyExpression - policyId - parameters;
346
+ ```
347
+
348
+ Examples:
349
+
350
+ - `risk.score > threshold`
351
+ - `principal.trustLevel < required`
352
+ - `device.notTrusted`
353
+
354
+ (Policy language comes in Step 4.)
355
+
356
+ ---
357
+
358
+ ## 7. AuthenticationAttempt Lifecycle (Flow-Driven)
359
+
360
+ The flow **drives the attempt**, not the other way around.
361
+
362
+ States:
363
+
364
+ - `Initialized`
365
+ - `InProgress`
366
+ - `AwaitingChallenge`
367
+ - `Succeeded`
368
+ - `Failed`
369
+
370
+ Rules:
371
+
372
+ - One flow per attempt
373
+ - Steps are executed sequentially
374
+ - Proofs are accumulated
375
+ - Finalization happens only at terminal state
376
+
377
+ ---
378
+
379
+ ## 8. Example Flows (Conceptual)
380
+
381
+ ### 8.1 Simple Password Flow
382
+
383
+ ```
384
+ Step 1: password
385
+ onSuccess → AUTHENTICATED
386
+ onFailure → FAILED
387
+ ```
388
+
389
+ ---
390
+
391
+ ### 8.2 Password + OTP (MFA)
392
+
393
+ ```
394
+ Step 1: password
395
+ onSuccess → Step 2
396
+ onFailure → FAILED
397
+
398
+ Step 2: otp
399
+ onSuccess → AUTHENTICATED
400
+ onFailure → FAILED
401
+ ```
402
+
403
+ ---
404
+
405
+ ### 8.3 Risk-Based Step-Up
406
+
407
+ ```
408
+ Step 1: password
409
+ onSuccess →
410
+ if risk.low → AUTHENTICATED
411
+ if risk.high → Step 2
412
+
413
+ Step 2: otp
414
+ onSuccess → AUTHENTICATED
415
+ onFailure → FAILED
416
+ ```
417
+
418
+ ---
419
+
420
+ ### 8.4 OAuth / Social Login
421
+
422
+ ```
423
+ Step 1: oauth_oidc
424
+ onSuccess → AUTHENTICATED
425
+ onFailure → FAILED
426
+ onChallenge → AWAITING_EXTERNAL_ASSERTION
427
+ ```
428
+
429
+ No redirects modeled. That’s infrastructure.
430
+
431
+ ---
432
+
433
+ ## 9. What Flows Explicitly Do NOT Know
434
+
435
+ Flows do **not** know about:
436
+
437
+ - HTTP redirects
438
+ - UI screens
439
+ - Cookies
440
+ - Tokens
441
+ - OAuth providers
442
+ - Mobile vs web
443
+ - DB schemas
444
+
445
+ They only know:
446
+
447
+ - Steps
448
+ - Transitions
449
+ - Policies
450
+
451
+ ---
452
+
453
+ ## 10. Extensibility Guarantees
454
+
455
+ With this DSL, you can:
456
+
457
+ - Add new auth methods without new flows
458
+ - Add new flows without code changes
459
+ - Customize enterprise flows via config
460
+ - Reuse flows across products
461
+ - Audit authentication behavior deterministically
462
+
463
+ ---
464
+
465
+ ## 11. Validation Checklist (Must Pass)
466
+
467
+ Before moving forward:
468
+
469
+ ✔ Flow is declarative ✔ No branching by method type ✔ No protocol assumptions ✔
470
+ No infrastructure knowledge ✔ Supports MFA and step-up ✔ Serializable and
471
+ versionable
472
+
473
+ If any fails → redesign.
474
+
475
+ ---
476
+
477
+ ## Step 2 Status
478
+
479
+ ✅ Authentication Flow DSL defined ✅ Orchestration decoupled from methods ✅
480
+ Enterprise-ready ✅ Hexagonal-safe
481
+
482
+ ---
483
+
484
+ # Step 3 — **AuthenticationAttempt Lifecycle (Aggregate Rules)**
485
+
486
+ This step defines **the heart of correctness**. If this aggregate is weak,
487
+ you’ll get replay attacks, broken MFA, and inconsistent auth state.
488
+
489
+ ---
490
+
491
+ ## 1. Purpose of AuthenticationAttempt
492
+
493
+ An **AuthenticationAttempt** represents:
494
+
495
+ > _One and only one execution of an authentication flow._
496
+
497
+ It exists to:
498
+
499
+ - Enforce invariants
500
+ - Track progress across steps
501
+ - Collect proofs
502
+ - Coordinate challenges
503
+ - Produce a single outcome
504
+
505
+ It is the **source of truth** for authentication state.
506
+
507
+ ---
508
+
509
+ ## 2. Why This Must Be an Aggregate Root
510
+
511
+ Because it controls **critical invariants**:
512
+
513
+ - A step cannot be skipped
514
+ - A proof cannot be reused
515
+ - An attempt cannot succeed twice
516
+ - A failed attempt cannot be resumed
517
+ - MFA ordering must be enforced
518
+
519
+ If this is not an aggregate → bugs are guaranteed.
520
+
521
+ ---
522
+
523
+ ## 3. AuthenticationAttempt Structure (Conceptual)
524
+
525
+ **Aggregate Root: AuthenticationAttempt**
526
+
527
+ **Key Attributes**
528
+
529
+ - AttemptId
530
+ - FlowId
531
+ - PrincipalId? (optional initially)
532
+ - CurrentStepId
533
+ - Status
534
+ - CollectedProofs
535
+ - StartedAt
536
+ - CompletedAt?
537
+
538
+ ---
539
+
540
+ ## 4. Attempt States (Strict State Machine)
541
+
542
+ Only these states are allowed:
543
+
544
+ 1. `Initialized`
545
+ 2. `InProgress`
546
+ 3. `AwaitingChallenge`
547
+ 4. `Succeeded`
548
+ 5. `Failed`
549
+
550
+ No others. No “partial success”.
551
+
552
+ ---
553
+
554
+ ## 5. State Transition Rules (Non-Negotiable)
555
+
556
+ ### 5.1 Initialization
557
+
558
+ - Created with a Flow
559
+ - No proofs
560
+ - No session
561
+ - Status = `Initialized`
562
+
563
+ Allowed transitions:
564
+
565
+ - → `InProgress`
566
+
567
+ ---
568
+
569
+ ### 5.2 InProgress
570
+
571
+ - Actively executing a flow step
572
+ - Accepts exactly **one proof per step**
573
+
574
+ Allowed transitions:
575
+
576
+ - → `AwaitingChallenge`
577
+ - → `Succeeded`
578
+ - → `Failed`
579
+
580
+ ---
581
+
582
+ ### 5.3 AwaitingChallenge
583
+
584
+ Used when:
585
+
586
+ - External action is required
587
+ - OTP sent
588
+ - OAuth assertion pending
589
+ - Push approval pending
590
+
591
+ Rules:
592
+
593
+ - No new step allowed
594
+ - Only challenge response accepted
595
+
596
+ Allowed transitions:
597
+
598
+ - → `InProgress`
599
+ - → `Failed`
600
+
601
+ ---
602
+
603
+ ### 5.4 Succeeded (Terminal)
604
+
605
+ Rules:
606
+
607
+ - Immutable
608
+ - Produces AuthenticationSession
609
+ - No further actions allowed
610
+
611
+ ---
612
+
613
+ ### 5.5 Failed (Terminal)
614
+
615
+ Rules:
616
+
617
+ - Immutable
618
+ - No retry inside same attempt
619
+ - New attempt required
620
+
621
+ ---
622
+
623
+ ## 6. Proof Handling Rules
624
+
625
+ Proofs are **append-only**.
626
+
627
+ Rules:
628
+
629
+ - One proof per step
630
+ - Proof must match expected AuthMethodType
631
+ - Proof must be verified before progressing
632
+ - Proofs cannot be modified or deleted
633
+
634
+ This guarantees:
635
+
636
+ - Auditability
637
+ - Determinism
638
+ - Replay prevention
639
+
640
+ ---
641
+
642
+ ## 7. Step Advancement Rules
643
+
644
+ The aggregate enforces:
645
+
646
+ - Steps must be executed in order
647
+ - Transition conditions must be satisfied
648
+ - Skipping steps is forbidden
649
+ - Optional steps are flow-defined, not attempt-defined
650
+
651
+ The attempt **does not decide** what the next step is. It **asks the flow**.
652
+
653
+ ---
654
+
655
+ ## 8. Failure Semantics (Important)
656
+
657
+ Failures are **final**.
658
+
659
+ Examples:
660
+
661
+ - Wrong password → Failed
662
+ - OTP expired → Failed
663
+ - OAuth assertion invalid → Failed
664
+
665
+ Retries:
666
+
667
+ - Require a **new AuthenticationAttempt**
668
+ - Rate limiting is policy/infrastructure concern
669
+
670
+ This avoids:
671
+
672
+ - State confusion
673
+ - Timing attacks
674
+ - Complex rollback logic
675
+
676
+ ---
677
+
678
+ ## 9. Relationship to Other Aggregates
679
+
680
+ - Uses **AuthenticationFlow** (read-only)
681
+ - Produces **AuthenticationSession**
682
+ - References **Principal**, but does not own it
683
+ - Uses **Policies**, but does not evaluate them
684
+
685
+ No bidirectional coupling.
686
+
687
+ ---
688
+
689
+ ## 10. What AuthenticationAttempt Does NOT Do
690
+
691
+ Explicitly forbidden:
692
+
693
+ - Creating credentials
694
+ - Issuing tokens
695
+ - Storing secrets
696
+ - Evaluating risk
697
+ - Talking to HTTP
698
+ - Calling providers
699
+
700
+ It enforces **process**, not mechanics.
701
+
702
+ ---
703
+
704
+ ## 11. Invariant Checklist (Must Always Hold)
705
+
706
+ ✔ One flow per attempt ✔ One terminal state only ✔ No step skipping ✔ No proof
707
+ reuse ✔ No resurrection after failure ✔ Deterministic outcome
708
+
709
+ If any invariant breaks → security issue.
710
+
711
+ ---
712
+
713
+ ## 12. Step 3 Status
714
+
715
+ ✅ Aggregate boundaries defined ✅ State machine enforced ✅ MFA-safe ✅
716
+ Replay-safe ✅ Audit-ready
717
+
718
+ ---
719
+
720
+ # Step 4 — **Authentication Policy Model (Risk, Conditions, Step-Up)**
721
+
722
+ This step defines **who is allowed to authenticate, under what conditions, and
723
+ with which strength** — without hard-coding logic.
724
+
725
+ If policies are not modeled cleanly, you will:
726
+
727
+ - Hard-code MFA rules
728
+ - Fork enterprise behavior
729
+ - Break extensibility
730
+ - Lose auditability
731
+
732
+ ---
733
+
734
+ ## 1. Purpose of Policy in Auth Domain
735
+
736
+ A **Policy** answers questions like:
737
+
738
+ - Is this authentication allowed?
739
+ - Is step-up required?
740
+ - Which flow should apply?
741
+ - Is this context risky?
742
+ - Is the current proof sufficient?
743
+
744
+ Policies **do not authenticate**. They **constrain and steer** authentication.
745
+
746
+ ---
747
+
748
+ ## 2. Core Principle (Non-Negotiable)
749
+
750
+ **Policies are declarative and evaluative — never procedural.**
751
+
752
+ No:
753
+
754
+ ```ts
755
+ if (ip === 'x') requireOtp();
756
+ ```
757
+
758
+ Yes:
759
+
760
+ - Policy definitions
761
+ - Policy evaluation results
762
+ - Policy-driven decisions
763
+
764
+ ---
765
+
766
+ ## 3. Policy as a First-Class Domain Concept
767
+
768
+ ### AuthenticationPolicy (Domain Object)
769
+
770
+ ```ts
771
+ AuthenticationPolicy
772
+ - policyId
773
+ - name
774
+ - scope
775
+ - rules: PolicyRule[]
776
+ - effect
777
+ ```
778
+
779
+ Rules:
780
+
781
+ - Immutable
782
+ - Versionable
783
+ - Serializable
784
+ - Configurable per tenant / environment
785
+
786
+ ---
787
+
788
+ ## 4. Policy Scope
789
+
790
+ Policies apply at different levels:
791
+
792
+ ```ts
793
+ PolicyScope =
794
+ | Global
795
+ | Principal
796
+ | AuthMethod
797
+ | AuthFlow
798
+ | Resource
799
+ ```
800
+
801
+ Examples:
802
+
803
+ - Global MFA enforcement
804
+ - Principal-specific restrictions
805
+ - Method-specific constraints
806
+ - Flow selection rules
807
+
808
+ ---
809
+
810
+ ## 5. Policy Rules (Atomic Conditions)
811
+
812
+ ### PolicyRule
813
+
814
+ ```ts
815
+ PolicyRule
816
+ - condition: ConditionExpression
817
+ - action: PolicyAction
818
+ ```
819
+
820
+ Each rule:
821
+
822
+ - Evaluates **one condition**
823
+ - Produces **one action**
824
+ - Has no side effects
825
+
826
+ ---
827
+
828
+ ## 6. Condition Model (What can be checked)
829
+
830
+ Conditions evaluate **context**, never infrastructure.
831
+
832
+ ```ts
833
+ ConditionExpression - subject - operator - value;
834
+ ```
835
+
836
+ ### Common Subjects
837
+
838
+ - risk.score
839
+ - principal.trustLevel
840
+ - device.trusted
841
+ - location.country
842
+ - time.window
843
+ - auth.method
844
+ - auth.factor
845
+ - attempt.count
846
+
847
+ ### Operators
848
+
849
+ - equals
850
+ - notEquals
851
+ - greaterThan
852
+ - lessThan
853
+ - in
854
+ - notIn
855
+
856
+ ---
857
+
858
+ ## 7. Policy Actions (What can be enforced)
859
+
860
+ Actions **do not perform authentication**.
861
+
862
+ ```ts
863
+ PolicyAction =
864
+ | Allow
865
+ | Deny
866
+ | RequireStepUp
867
+ | SelectFlow
868
+ | LimitTrustLevel
869
+ ```
870
+
871
+ Examples:
872
+
873
+ - Require OTP if risk > threshold
874
+ - Deny auth from blocked country
875
+ - Force enterprise SSO
876
+ - Downgrade session trust
877
+
878
+ ---
879
+
880
+ ## 8. Policy Evaluation Result
881
+
882
+ Policies return **decisions**, not behavior.
883
+
884
+ ```ts
885
+ PolicyEvaluationResult
886
+ - decision
887
+ - requiredFlow?
888
+ - requiredAuthFactors?
889
+ - maxTrustLevel?
890
+ - reasons[]
891
+ ```
892
+
893
+ This allows:
894
+
895
+ - Explainability
896
+ - Auditing
897
+ - Compliance
898
+
899
+ ---
900
+
901
+ ## 9. Policy Evaluation Responsibility
902
+
903
+ Policies are **evaluated by a Domain Service**, not entities.
904
+
905
+ ```ts
906
+ AuthenticationPolicyEvaluator
907
+ - evaluate(context): PolicyEvaluationResult
908
+ ```
909
+
910
+ Context includes:
911
+
912
+ - Principal snapshot
913
+ - AuthenticationAttempt snapshot
914
+ - Device/context snapshot
915
+ - Risk assessment (via port)
916
+
917
+ ---
918
+
919
+ ## 10. Relationship with Authentication Flow
920
+
921
+ Policies can:
922
+
923
+ - Select a flow
924
+ - Alter transitions
925
+ - Require additional steps
926
+
927
+ Flows **reference policies**, but do not contain logic.
928
+
929
+ This separation allows:
930
+
931
+ - Same flow, different behavior
932
+ - Enterprise overrides
933
+ - Runtime reconfiguration
934
+
935
+ ---
936
+
937
+ ## 11. Example Policies (Conceptual)
938
+
939
+ ### 11.1 Risk-Based MFA
940
+
941
+ ```
942
+ IF risk.score > 70
943
+ THEN RequireStepUp (otp)
944
+ ```
945
+
946
+ ---
947
+
948
+ ### 11.2 Geo Restriction
949
+
950
+ ```
951
+ IF location.country IN blockedCountries
952
+ THEN Deny
953
+ ```
954
+
955
+ ---
956
+
957
+ ### 11.3 Trust Downgrade
958
+
959
+ ```
960
+ IF device.trusted = false
961
+ THEN LimitTrustLevel = LOW
962
+ ```
963
+
964
+ ---
965
+
966
+ ### 11.4 Flow Selection
967
+
968
+ ```
969
+ IF principal.type = Service
970
+ THEN SelectFlow = m2m_flow
971
+ ```
972
+
973
+ ---
974
+
975
+ ## 12. What Policies Explicitly Do NOT Do
976
+
977
+ Forbidden:
978
+
979
+ - Issuing challenges
980
+ - Sending OTPs
981
+ - Creating sessions
982
+ - Calling providers
983
+ - Accessing databases directly
984
+ - Knowing HTTP headers
985
+
986
+ They only **decide**.
987
+
988
+ ---
989
+
990
+ ## 13. Extensibility Guarantees
991
+
992
+ With this model you can:
993
+
994
+ - Add new conditions without changing flows
995
+ - Add new actions without breaking domain
996
+ - Support enterprise policy engines later
997
+ - Audit decisions deterministically
998
+
999
+ ---
1000
+
1001
+ ## 14. Step 4 Status
1002
+
1003
+ ✅ Policy model defined ✅ Risk-adaptive ready ✅ Enterprise-grade ✅
1004
+ Explainable and auditable
1005
+
1006
+ ---
1007
+
1008
+ # Step 5 — **Credential Lifecycle Modeling**
1009
+
1010
+ This step defines **what a credential is**, how it is created, validated,
1011
+ rotated, revoked, and expired — without storing secrets or coupling to storage.
1012
+
1013
+ If credential lifecycle is vague, security degrades fast.
1014
+
1015
+ ---
1016
+
1017
+ ## 1. Purpose of Credential in Auth Domain
1018
+
1019
+ A **Credential** represents:
1020
+
1021
+ > _A verifiable authentication capability bound to a Principal._
1022
+
1023
+ It is **not**:
1024
+
1025
+ - A password hash
1026
+ - An OTP secret
1027
+ - A token
1028
+ - A provider artifact
1029
+
1030
+ Those are **infrastructure details**.
1031
+
1032
+ ---
1033
+
1034
+ ## 2. Credential as a Domain Entity
1035
+
1036
+ ### Credential (Entity)
1037
+
1038
+ ```ts
1039
+ Credential
1040
+ - CredentialId
1041
+ - PrincipalId
1042
+ - AuthMethodType
1043
+ - AuthFactorType
1044
+ - Status
1045
+ - IssuedAt
1046
+ - ExpiresAt?
1047
+ - LastUsedAt?
1048
+ - Metadata
1049
+ ```
1050
+
1051
+ ---
1052
+
1053
+ ## 3. Credential Status (Finite State)
1054
+
1055
+ ```ts
1056
+ CredentialStatus =
1057
+ | Active
1058
+ | Suspended
1059
+ | Revoked
1060
+ | Expired
1061
+ | Compromised
1062
+ ```
1063
+
1064
+ Rules:
1065
+
1066
+ - Revoked and Compromised are terminal
1067
+ - Expired is time-based
1068
+ - Suspended is reversible
1069
+
1070
+ ---
1071
+
1072
+ ## 4. Credential Invariants (Strict)
1073
+
1074
+ A credential must always satisfy:
1075
+
1076
+ - Belongs to exactly one Principal
1077
+ - Is bound to exactly one Auth Method
1078
+ - Cannot be reused across principals
1079
+ - Cannot be reactivated after Revocation
1080
+ - Cannot authenticate if not Active
1081
+ - Cannot exist without lifecycle metadata
1082
+
1083
+ Violation = security bug.
1084
+
1085
+ ---
1086
+
1087
+ ## 5. Credential Creation Rules
1088
+
1089
+ Credential creation:
1090
+
1091
+ - Is explicit
1092
+ - Requires policy approval
1093
+ - Produces **no secret** in domain
1094
+ - Delegates material generation to infrastructure
1095
+
1096
+ Example:
1097
+
1098
+ - Domain: “Create OTP credential”
1099
+ - Infra: Generates secret, stores it securely
1100
+
1101
+ ---
1102
+
1103
+ ## 6. Credential Usage Rules
1104
+
1105
+ On each successful authentication:
1106
+
1107
+ - Credential status must be Active
1108
+ - Expiration must be checked
1109
+ - Usage timestamp may be updated
1110
+ - Compromise signals may suspend or revoke
1111
+
1112
+ Credential usage is **observed**, not enforced here.
1113
+
1114
+ ---
1115
+
1116
+ ## 7. Credential Rotation & Replacement
1117
+
1118
+ Rotation is modeled as:
1119
+
1120
+ - Create new credential
1121
+ - Activate new
1122
+ - Suspend or revoke old
1123
+
1124
+ No mutation-in-place.
1125
+
1126
+ This allows:
1127
+
1128
+ - Auditability
1129
+ - Rollback
1130
+ - Compliance
1131
+
1132
+ ---
1133
+
1134
+ ## 8. Credential Revocation
1135
+
1136
+ Revocation reasons:
1137
+
1138
+ - User action
1139
+ - Admin action
1140
+ - Policy decision
1141
+ - Risk detection
1142
+ - Breach response
1143
+
1144
+ Revocation:
1145
+
1146
+ - Is immediate
1147
+ - Is irreversible
1148
+ - Must propagate to infra adapters
1149
+
1150
+ ---
1151
+
1152
+ ## 9. Credential Expiration
1153
+
1154
+ Expiration:
1155
+
1156
+ - Is time-based
1157
+ - Evaluated at authentication time
1158
+ - Does not delete credential
1159
+ - Transitions to Expired
1160
+
1161
+ Deletion is **not** domain responsibility.
1162
+
1163
+ ---
1164
+
1165
+ ## 10. Relationship to AuthenticationAttempt
1166
+
1167
+ - Attempts **reference** credentials
1168
+ - Attempts do not own credentials
1169
+ - Credential state is checked during verification
1170
+ - No attempt may mutate credential directly
1171
+
1172
+ ---
1173
+
1174
+ ## 11. Credential Types (Examples)
1175
+
1176
+ | Method | Credential Meaning |
1177
+ | --------- | ---------------------- |
1178
+ | Password | Knowledge credential |
1179
+ | OTP | Possession credential |
1180
+ | OAuth | Delegated credential |
1181
+ | API Token | Possession credential |
1182
+ | Passkey | Possession + inherence |
1183
+
1184
+ Types are **data**, not inheritance.
1185
+
1186
+ ---
1187
+
1188
+ ## 12. What Credential Does NOT Know
1189
+
1190
+ Explicitly forbidden:
1191
+
1192
+ - Hash algorithms
1193
+ - OTP secrets
1194
+ - Token formats
1195
+ - Storage engines
1196
+ - Providers
1197
+ - Encryption
1198
+
1199
+ Those live behind ports.
1200
+
1201
+ ---
1202
+
1203
+ ## 13. Ports Related to Credentials
1204
+
1205
+ ```ts
1206
+ CredentialRepository;
1207
+ CredentialMaterialStore(infra);
1208
+ CredentialUsageReporter;
1209
+ CredentialRevocationPublisher;
1210
+ ```
1211
+
1212
+ Domain only depends on interfaces.
1213
+
1214
+ ---
1215
+
1216
+ ## 14. Extensibility Guarantees
1217
+
1218
+ With this model:
1219
+
1220
+ - New credential types require no domain change
1221
+ - Infra can store secrets however it wants
1222
+ - Enterprise policies can control lifecycle
1223
+ - Auditing is deterministic
1224
+
1225
+ ---
1226
+
1227
+ ## 15. Step 5 Status
1228
+
1229
+ ✅ Credential lifecycle defined ✅ Security invariants enforced ✅
1230
+ Storage-agnostic ✅ Enterprise-ready
1231
+
1232
+ ---
1233
+
1234
+ We continue. This is the **last foundational domain step**.
1235
+
1236
+ ---
1237
+
1238
+ # Step 6 — **AuthenticationSession & Trust Levels**
1239
+
1240
+ This step defines **what “being authenticated” actually means** in your system,
1241
+ independent of tokens, cookies, or transport.
1242
+
1243
+ If this is weak, authorization, SSO, and enterprise security all collapse.
1244
+
1245
+ ---
1246
+
1247
+ ## 1. Purpose of AuthenticationSession
1248
+
1249
+ An **AuthenticationSession** represents:
1250
+
1251
+ > _A time-bounded, trust-scoped result of a successful authentication._
1252
+
1253
+ It is:
1254
+
1255
+ - The output of Authentication
1256
+ - The input to Authorization
1257
+ - The anchor for SSO, re-auth, and step-up
1258
+
1259
+ It is **not**:
1260
+
1261
+ - A cookie
1262
+ - A JWT
1263
+ - A refresh token
1264
+ - An HTTP session
1265
+
1266
+ Those are representations.
1267
+
1268
+ ---
1269
+
1270
+ ## 2. AuthenticationSession as Aggregate Root
1271
+
1272
+ ### AuthenticationSession (Aggregate Root)
1273
+
1274
+ ```ts
1275
+ AuthenticationSession -
1276
+ SessionId -
1277
+ PrincipalId -
1278
+ FlowId -
1279
+ IssuedAt -
1280
+ ExpiresAt -
1281
+ TrustLevel -
1282
+ AuthFactorsUsed -
1283
+ ContextSnapshot -
1284
+ Status;
1285
+ ```
1286
+
1287
+ ---
1288
+
1289
+ ## 3. Session Status (Finite State)
1290
+
1291
+ ```ts
1292
+ SessionStatus =
1293
+ | Active
1294
+ | Expired
1295
+ | Revoked
1296
+ ```
1297
+
1298
+ Rules:
1299
+
1300
+ - Expired is time-based
1301
+ - Revoked is explicit and terminal
1302
+ - Active is the only usable state
1303
+
1304
+ ---
1305
+
1306
+ ## 4. Trust Level (Critical Concept)
1307
+
1308
+ ### TrustLevel (Value Object)
1309
+
1310
+ Trust is **not binary**.
1311
+
1312
+ ```ts
1313
+ TrustLevel =
1314
+ | Anonymous
1315
+ | Low
1316
+ | Medium
1317
+ | High
1318
+ ```
1319
+
1320
+ Interpretation:
1321
+
1322
+ - **Anonymous** → unauthenticated
1323
+ - **Low** → weak auth (magic link, social)
1324
+ - **Medium** → single strong factor
1325
+ - **High** → MFA / hardware-backed
1326
+
1327
+ Trust is:
1328
+
1329
+ - Computed from proofs + policies
1330
+ - Stored in session
1331
+ - Used by authorization
1332
+
1333
+ ---
1334
+
1335
+ ## 5. Trust Level Invariants
1336
+
1337
+ - TrustLevel is **assigned at session creation**
1338
+ - TrustLevel can be **downgraded**
1339
+ - TrustLevel can **never be upgraded in-place**
1340
+ - Upgrade requires **new AuthenticationAttempt**
1341
+
1342
+ This prevents silent privilege escalation.
1343
+
1344
+ ---
1345
+
1346
+ ## 6. Relationship to AuthenticationAttempt
1347
+
1348
+ - Exactly one session per successful attempt
1349
+ - Attempt produces session
1350
+ - Session references attempt context (read-only)
1351
+ - Session lifecycle is independent afterward
1352
+
1353
+ No circular dependency.
1354
+
1355
+ ---
1356
+
1357
+ ## 7. Context Snapshot (Why It Exists)
1358
+
1359
+ ### ContextSnapshot (Value Object)
1360
+
1361
+ Captures authentication context **at time of issuance**:
1362
+
1363
+ - Device trust
1364
+ - Location
1365
+ - Risk score
1366
+ - Auth methods used
1367
+ - Policies applied
1368
+
1369
+ Why:
1370
+
1371
+ - Auditability
1372
+ - Compliance
1373
+ - Forensic analysis
1374
+ - Future policy checks
1375
+
1376
+ Context is **immutable**.
1377
+
1378
+ ---
1379
+
1380
+ ## 8. Session Expiration Rules
1381
+
1382
+ Expiration is:
1383
+
1384
+ - Deterministic
1385
+ - Policy-driven
1386
+ - Evaluated by infrastructure
1387
+ - Reflected in domain state
1388
+
1389
+ Domain does not:
1390
+
1391
+ - Refresh sessions
1392
+ - Slide expiration
1393
+ - Issue refresh tokens
1394
+
1395
+ Those are adapters.
1396
+
1397
+ ---
1398
+
1399
+ ## 9. Session Revocation
1400
+
1401
+ Revocation triggers:
1402
+
1403
+ - User logout
1404
+ - Admin action
1405
+ - Credential revocation
1406
+ - Risk detection
1407
+ - Policy violation
1408
+
1409
+ Revocation:
1410
+
1411
+ - Is explicit
1412
+ - Is immediate
1413
+ - Invalidates all representations
1414
+
1415
+ ---
1416
+
1417
+ ## 10. SSO Compatibility (Important)
1418
+
1419
+ SSO is simply:
1420
+
1421
+ - Multiple representations
1422
+ - One AuthenticationSession
1423
+
1424
+ This model supports:
1425
+
1426
+ - Web SSO
1427
+ - Mobile SSO
1428
+ - API SSO
1429
+ - Cross-app SSO
1430
+
1431
+ Without special logic.
1432
+
1433
+ ---
1434
+
1435
+ ## 11. What AuthenticationSession Does NOT Know
1436
+
1437
+ Explicitly forbidden:
1438
+
1439
+ - JWT claims
1440
+ - Cookies
1441
+ - Headers
1442
+ - OAuth tokens
1443
+ - HTTP
1444
+ - Storage engine
1445
+
1446
+ It only knows **meaning**, not format.
1447
+
1448
+ ---
1449
+
1450
+ ## 12. Ports Related to Sessions
1451
+
1452
+ ```ts
1453
+ AuthenticationSessionRepository;
1454
+ SessionRevocationPublisher;
1455
+ SessionExpirationScheduler;
1456
+ SessionRepresentationFactory(infra);
1457
+ ```
1458
+
1459
+ Domain defines contracts only.
1460
+
1461
+ ---
1462
+
1463
+ ## 13. Extensibility Guarantees
1464
+
1465
+ With this model:
1466
+
1467
+ - You can change token formats freely
1468
+ - You can support SSO without refactor
1469
+ - You can add step-up auth cleanly
1470
+ - You can audit auth decisions years later
1471
+
1472
+ ---
1473
+
1474
+ ## 14. Step 6 Status
1475
+
1476
+ ✅ AuthenticationSession modeled ✅ Trust levels explicit ✅ Step-up safe ✅
1477
+ Authorization-ready ✅ Enterprise-grade
1478
+
1479
+ ---
1480
+
1481
+ # 🎯 Foundation Complete
1482
+
1483
+ You now have a **complete, extensible, production-grade Auth Domain**:
1484
+
1485
+ 1. Auth Method SPI
1486
+ 2. Authentication Flow DSL
1487
+ 3. AuthenticationAttempt lifecycle
1488
+ 4. Policy model
1489
+ 5. Credential lifecycle
1490
+ 6. AuthenticationSession & Trust