Finish FLEX-WP-0019 layer-model v0.7 conformance
Close the remaining PDP obligations: mechanical layer declaration check, registry-snapshot digest in provenance, explicit allow TTL, per-input-class freshness deadlines, and the published decision-record contract. Document the canonical request digest as the §6.4.2 replay test. Assistant: grok Assistant-Session: 01a06256-fb71-7102-b3a9-27e6734257d0
This commit is contained in:
parent
9689894c15
commit
56940727bf
32 changed files with 1194 additions and 111 deletions
|
|
@ -10,6 +10,7 @@ import (
|
|||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/netkingdom/flex-auth/internal/policy"
|
||||
"github.com/netkingdom/flex-auth/internal/registry"
|
||||
|
|
@ -24,6 +25,7 @@ type Engine struct {
|
|||
mu sync.RWMutex
|
||||
history map[string]api.DecisionEnvelope
|
||||
log DecisionRecorder
|
||||
clock func() time.Time
|
||||
}
|
||||
|
||||
// DecisionRecorder persists decision envelopes.
|
||||
|
|
@ -82,6 +84,23 @@ func (e *Engine) SetDecisionLog(log DecisionRecorder) {
|
|||
e.log = log
|
||||
}
|
||||
|
||||
// SetClock overrides the engine clock. Tests use this to pin allow lifetimes.
|
||||
func (e *Engine) SetClock(clock func() time.Time) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
e.clock = clock
|
||||
}
|
||||
|
||||
func (e *Engine) now() time.Time {
|
||||
e.mu.RLock()
|
||||
clock := e.clock
|
||||
e.mu.RUnlock()
|
||||
if clock != nil {
|
||||
return clock().UTC()
|
||||
}
|
||||
return time.Now().UTC()
|
||||
}
|
||||
|
||||
// Check evaluates one subject/action/resource request.
|
||||
func (e *Engine) Check(ctx context.Context, request api.CheckRequest) (api.DecisionEnvelope, error) {
|
||||
normalized, facts := e.normalizeRequest(request)
|
||||
|
|
@ -307,13 +326,19 @@ func (e *Engine) envelope(request api.CheckRequest, expectation api.DecisionExpe
|
|||
"matched_relationship": facts.matchedRelationship,
|
||||
},
|
||||
Provenance: api.DecisionProvenance{
|
||||
Evaluator: "flex-auth/local",
|
||||
Mode: "standalone",
|
||||
PolicyPackage: e.policy.Metadata.ID,
|
||||
PolicyVersion: e.policy.Metadata.Version,
|
||||
Evaluator: "flex-auth/local",
|
||||
Mode: "standalone",
|
||||
PolicyPackage: e.policy.Metadata.ID,
|
||||
PolicyVersion: e.policy.Metadata.Version,
|
||||
PolicyPackageDigest: e.policy.Digest(),
|
||||
RegistrySnapshotDigest: e.store.Digest(),
|
||||
},
|
||||
Caring: e.caringDecisionMetadata(facts.descriptor, expectation.ConformanceFindings),
|
||||
}
|
||||
api.CompleteDecision(&envelope, request, api.DecisionCompletion{
|
||||
AllowTTL: e.policy.Metadata.AllowTTL,
|
||||
Now: e.now(),
|
||||
})
|
||||
envelope.ID = decisionID(e.policy.Metadata, request, envelope)
|
||||
return envelope
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue