Finish FLEX-WP-0019 layer-model v0.7 conformance
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Container Image / build-and-push (push) Successful in 57s

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:
tegwick 2026-09-03 23:48:45 +02:00
parent 9689894c15
commit 56940727bf
32 changed files with 1194 additions and 111 deletions

View file

@ -16,9 +16,12 @@ import (
// Adapter delegates checks, directory writes, and policy bundle publication to
// Topaz while preserving flex-auth request and decision contracts.
type Adapter struct {
client Client
policyPackage string
policyVersion string
client Client
policyPackage string
policyVersion string
policyPackageDigest string
registrySnapshotDigest string
allowTTL string
}
// New creates a Topaz adapter.
@ -27,9 +30,12 @@ func New(client Client, options Options) (*Adapter, error) {
return nil, fmt.Errorf("topaz client is required")
}
return &Adapter{
client: client,
policyPackage: options.PolicyPackage,
policyVersion: options.PolicyVersion,
client: client,
policyPackage: options.PolicyPackage,
policyVersion: options.PolicyVersion,
policyPackageDigest: options.PolicyPackageDigest,
registrySnapshotDigest: options.RegistrySnapshotDigest,
allowTTL: options.AllowTTL,
}, nil
}
@ -202,6 +208,7 @@ func (a *Adapter) envelope(request api.CheckRequest, topazRequest DirectoryCheck
},
Caring: caringDecisionMetadata(request, firstDescriptor(request.CaringContext, result.CaringDescriptor), result.ConformanceFindings, result.ExposureEvent),
}
envelope = a.finish(request, envelope)
envelope.ID = decisionID(policyPackage, policyVersion, request, envelope.Effect, envelope.Reason, result.DirectoryETag)
if envelope.Caring != nil && envelope.Caring.ExposureEvent != nil && envelope.Caring.ExposureEvent.ID == "" {
envelope.Caring.ExposureEvent.ID = envelope.ID + ":exposure"
@ -237,10 +244,22 @@ func (a *Adapter) failureEnvelope(request api.CheckRequest, topazRequest Directo
},
Caring: caringDecisionMetadata(request, request.CaringContext, findings, nil),
}
envelope = a.finish(request, envelope)
envelope.ID = decisionID(a.policyPackage, policyVersion, request, envelope.Effect, envelope.Reason, "")
return envelope
}
func (a *Adapter) finish(request api.CheckRequest, envelope api.DecisionEnvelope) api.DecisionEnvelope {
if envelope.Provenance.RegistrySnapshotDigest == "" {
envelope.Provenance.RegistrySnapshotDigest = a.registrySnapshotDigest
}
if envelope.Provenance.PolicyPackageDigest == "" {
envelope.Provenance.PolicyPackageDigest = a.policyPackageDigest
}
api.CompleteDecision(&envelope, request, api.DecisionCompletion{AllowTTL: a.allowTTL})
return envelope
}
func addTopazDiagnostics(diagnostics map[string]any, request DirectoryCheckRequest, failure string) {
diagnostics["adapter"] = "topaz"
diagnostics["mode"] = DelegatedMode

View file

@ -86,6 +86,12 @@ func TestAdapterCheckWrapsTopazAllowInFlexAuthEnvelope(t *testing.T) {
if got.Provenance.DirectoryETag != "etag:rel-42" {
t.Fatalf("DirectoryETag = %q", got.Provenance.DirectoryETag)
}
if got.Provenance.RegistrySnapshotDigest != "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" {
t.Fatalf("RegistrySnapshotDigest = %q", got.Provenance.RegistrySnapshotDigest)
}
if got.Lifetime == nil || got.Lifetime.Kind != api.DecisionLifetimeTTL {
t.Fatalf("lifetime = %+v; want default ttl", got.Lifetime)
}
if got.Diagnostics["topaz_object_type"] != "document" || got.Diagnostics["topaz_subject_type"] != "user" {
t.Fatalf("diagnostics = %+v; want Topaz check shape", got.Diagnostics)
}
@ -201,8 +207,9 @@ func newAdapter(t *testing.T, client *fakeClient) *topaz.Adapter {
t.Helper()
adapter, err := topaz.New(client, topaz.Options{
PolicyPackage: "markitect.documents.internal-read",
PolicyVersion: "v1",
PolicyPackage: "markitect.documents.internal-read",
PolicyVersion: "v1",
RegistrySnapshotDigest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
})
if err != nil {
t.Fatalf("New: %v", err)

View file

@ -41,8 +41,11 @@ type BundleSink interface {
// Options configures the adapter without leaking Topaz-specific types into the
// public flex-auth API.
type Options struct {
PolicyPackage string
PolicyVersion string
PolicyPackage string
PolicyVersion string
PolicyPackageDigest string
RegistrySnapshotDigest string
AllowTTL string
}
// DirectoryObject is the Topaz directory object shape used by the REST